【问题标题】:Unmarshal a REST response without using @XMLRootElement annotation在不使用 @XMLRootElement 注释的情况下解组 REST 响应
【发布时间】:2012-03-16 08:29:33
【问题描述】:

好的,我到处寻找答案。快把我逼疯了。

我需要做的就是解组一个非常简单的 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]

【问题讨论】:

    标签: web-services rest jaxb wsdl resttemplate


    【解决方案1】:

    几个月前我忘了发布这个,我可能应该跟进解决方案。 此解决方案还将 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();
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多