【问题标题】:Spring RestTemplate not accepting JAXBElementSpring RestTemplate 不接受 JAXBElement
【发布时间】:2016-07-20 12:23:53
【问题描述】:

我正在尝试使用 RestTemplate 对服务进行简单的 POST。我拥有的 XSD 不会生成根元素,而是具有根元素类型。但是 ObjectFactory.createFoo(FooType) 给了我试图发布的 JAXBElement,但没有这样做,但出现以下异常:

org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [com.foo.FooType] and content type [application/xml]

这是我调用其余服务的代码

HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_XML);
                    HttpEntity<FooType> entity = new HttpEntity<FooType>(request.getValue(),headers);
                    JAXBElement<ResponseType> response = restTemplate.postForObject(esbReplaceNumberListURI, entity, JAXBElement.class);

在通过 StackOverflow 中的答案后,我尝试将 Jaxb2Marshaller(of Spring O/X jar ) 添加到 RestTemplate,并将 setSupportJaxbElementClass 设置为 true。这没有帮助。

我正在构建我的请求对象,如下所示,它给了我 JAXBElement

  JAXBElement<FooType> request =  ObjectFactory.createFoo(FooType);

然后在发布时我执行 request.getValue() 如下:

HttpEntity<FooType> entity = new HttpEntity<FooType>(request.getValue(),headers);

我的 Spring 配置如下:

@Bean
    public RestTemplate restTemplate() {

        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(getMarshallingHttpMessageConverter());
        return restTemplate;
    }

    @Bean
    public MarshallingHttpMessageConverter getMarshallingHttpMessageConverter() {
        MarshallingHttpMessageConverter marshallingConverter = new MarshallingHttpMessageConverter();
        marshallingConverter.setMarshaller(jaxb2Marshaller());
        marshallingConverter.setUnmarshaller(jaxb2Marshaller());
        marshallingConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_XML, MediaType.TEXT_XML));

        return marshallingConverter;
    }

    @Bean
    public Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setSupportJaxbElementClass(Boolean.TRUE);
        marshaller.setPackagesToScan("com.foo.domain.*");
        return marshaller;
    }

使用 Spring-Boot 1.3.5.RELEASE,而后者又使用 Spring 4.2.6.RELEASE。 我无法解决这个问题。非常感谢任何帮助。

【问题讨论】:

    标签: spring resttemplate jaxb2


    【解决方案1】:

    我有 75% 的把握你应该拥有marshaller.setPackagesToScan("com.foo.domain");,而不是marshaller.setPackagesToScan("com.foo.domain.*");。请注意* 的缺失——我相信它试图找到一个名称为* 的包,这显然不存在。

    来源:

    Jaxb2Marshaller#setPackagesToScan:

    这是使用基于 Spring 的搜索,因此类似于 Spring 的组件扫描功能({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner})

    这表明它可能与Spring Reference 中描述的相同,它说:

    以下是使用 XML 的替代方法

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:component-scan base-package="org.example"/>
    
    </beans>
    

    其中有&lt;context:component-scan base-package="org.example"/&gt;

    【讨论】:

    • 感谢您的回复和 +1 提供有关包裹声明的详细信息。我按照你的建议改了。仍然看到相同的异常。我也尝试直接给出类名 FooType。得到同样的错误。
    • 啊,我现在明白了!你不应该通过request.getValue() - 你应该通过request。我怀疑FooType 缺少@XmlRootElement 注释,这就是为什么它必须包装在JAXBElement 中。因此,HttpEntity&lt;JAXBElement&lt;FooType&gt;&gt; entity = new HttpEntity&lt;&gt;(request, headers);(假设 Java 7+)。
    • HttpEntity> entity = new HttpEntity(request, headers);对我也不起作用。
    猜你喜欢
    • 1970-01-01
    • 2017-10-10
    • 2019-12-03
    • 1970-01-01
    • 2017-03-02
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多