在不使用@XMLRootElement批注的情况下解组REST响应

时间:2012-03-16 08:29:33

标签: web-services rest jaxb wsdl resttemplate

好的,我到处寻找答案。这让我疯了。

我需要做的就是解组一个非常简单的Web服务响应。唯一的问题是,我使用的是没有@XmlRootElement注释的生成源文件。我无法编辑此生成的源文件以添加@XmlRootElement。我需要“按原样”使用它。

这是我当前的代码,但是导致此帖子底部显示错误。我试过使用JAXBElement包装但无济于事。有人可以给我一些我需要的代码吗?我不知道如何使用"QName"s等。

以下代码适用于具有@XmlRootElement

的类
 MyGeneratedClass response = restTemplate.getForObject("url to webservice!"),
     MyGeneratedClass.class);

 return response

可悲的是,在这种情况下产生了这个错误。请帮我解组REST响应!

 Could not extract response: no suitable HttpMessageConverter found for response
    type [MyGeneratedClass] and content type [application/xml;version=1]

3 个答案:

答案 0 :(得分:3)

我忘记了几个月前发布的内容,我应该跟着解决方案。 此解决方案还会在请求标头中添加cookie,但您可以忽略它。 如果生成的源文件没有@XmlRootElement批注,则可以按如下方式解组:

// Cookie setting
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Cookie", "myCookie=value");
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);

HttpEntity<String> response = restTemplate.exchange("web service url"), 
    HttpMethod.GET, requestEntity, String.class);

// Unmarshalling
JAXBElement<MyGeneratedClass> result = 
    (JAXBElement<MyGeneratedClass>) unmarshaller.unmarshal(
        new StreamSource(new ByteArrayInputStream(response.getBody().getBytes())));

return result.getValue();

答案 1 :(得分:1)

Spring的RestTemplate依靠HttpMessageConverter将对象解组为XML。更具体地说,Jaxb2RootElementHttpMessageConverter.canWrite方法负责您所看到的错误。即使您要覆盖canWrite方法而不关心是否存在XmlRootElement注释,JAXB也无法解组该对象。

解决此限制的一种方法是重写Jaxb2RootElementHttpMessageConverter.canWrite以不检查是否存在XmlRootElement批注,并将EclipseLink的Moxy JAXB实现与映射文件一起使用。在映射文件中,您可以指定XmlRootElement批注的等效项,从而允许您在不使用Java类中的批注的情况下使用JAXB。

答案 2 :(得分:1)

Spring的RestTemplate通常与org.springframework.oxm.jaxb.Jaxb2Marshaller一起使用。不幸的是,该类默认情况下属性supportJaxbElementClass设置为false:(

Spring无处记录了这个属性,关于Spring论坛上的RestTemplate / JAXBELement的许多问题都没有答案:((((

幸运的是,你可以配置Jaxb2Marshaller,将其属性supportJaxbElementClass设置为true!

RestTemplate的以下示例配置将正确编组和解组JAXBElement类型的对象

<beans>
  <bean id="httpClient" class="org.apache.http.impl.client.DefaultHttpClient">
    <constructor-arg>
      <bean class="org.apache.http.impl.conn.PoolingClientConnectionManager" />
    </constructor-arg>
  </bean>

  <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>
      <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
        <constructor-arg ref="httpClient" />
      </bean>
    </constructor-arg>
    <!-- Configure the Rest template to translate between XML and JAXB -->
    <property name="messageConverters">
      <list>
        <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
          <property name="marshaller" ref="jaxbMarshaller" />
          <property name="unmarshaller" ref="jaxbMarshaller" />
        </bean>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>        
      </list>
    </property>
  </bean>
  <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="supportJaxbElementClass" value = "true"/>
    <property name="packagesToScan">
      <list>
        <value>com.myorg.path.to.JAXB.classes</value>
      </list>
    </property>
  </bean>
</beans>
相关问题