복붙노트

[SPRING] Spring RESTful 클라이언트 : 루트 태그 예외

SPRING

Spring RESTful 클라이언트 : 루트 태그 예외

이 샘플 http://thekspace.com/home/component/content/article/57-restful-clients-in-spring-3.html 다음 RestTemplate을 사용하여 RESTFull 호출에서 결과를 구문 분석하려고합니다.

XML 응답은 다음과 같습니다.

<brands>
    <brand>
        <nodeRef>1111111</nodeRef>
        <name>Test</name>
    </brand>
</brands>

먼저 application-context.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <property name="messageConverters">
            <list>
                <bean id="messageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                    <property name="marshaller" ref="xstreamMarshaller" />
                    <property name="unmarshaller" ref="xstreamMarshaller" />
                </bean>
            </list>
        </property>
    </bean>

    <bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
            <props>
                <prop key="brand">com.kipcast.dataModel.drugs.bean.BrandViewList</prop>
            </props>
        </property>
    </bean>


</beans>

com.kipcast.dataModel.drugs.bean.BrandViewList 클래스는 @XStreamAlias ​​( "브랜드")가 정의 된 bean입니다.

나머지는 어떻게 호출합니까?

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml", WebscriptCaller.class); 
RestTemplate restTemplate = applicationContext.getBean("restTemplate", RestTemplate.class);     

String url = "http://localhost:8081/alfresco/service/search/brand.xml?q={keyword}&alf_ticket={ticket}"; 
List<BrandViewList> results = (List<BrandViewList>) restTemplate.getForObject(url, List.class, params);

WebscriptCaller.class는이 지침을 실행하는 클래스입니다.

그것을 실행하려고하면 getForObject ()가 실패하고 해당 예외가 발생합니다.

XStream unmarshalling exception; nested exception is com.thoughtworks.xstream.mapper.CannotResolveClassException: brands

내 질문은, 어떻게 해결할 수 있습니까? 왜 이런 종류의 예외가 생길까요? 어떻게 루트 태그를 건너 뛰라고 말할 수 있습니까?

-------------- 업데이트 됨 -------------- 특히 몇 가지 문제가 수정되었습니다.

List<Brand> brandViewList = (List<Brand>) restTemplate.getForObject(url, Brand.class, params);

결과는 다음과 같습니다.

org.springframework.http.converter.HttpMessageNotReadableException: Could not read [class com.kipcast.dataModel.drugs.bean.Brand]; nested exception is org.springframework.oxm.UnmarshallingFailureException: XStream unmarshalling exception; nested exception is com.thoughtworks.xstream.converters.ConversionException: nodeRef : nodeRef
---- Debugging information ----
message             : nodeRef
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : nodeRef
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /brands/brand/nodeRef
line number         : 3
class[1]            : com.kipcast.dataModel.drugs.bean.Brands
converter-type[1]   : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version             : null
-------------------------------

해결법

  1. ==============================

    1.편집 : 관련 정보 만 포함하도록 업데이트 됨

    편집 : 관련 정보 만 포함하도록 업데이트 됨

    "브랜드"및 "브랜드"태그를 처리하는 고유 한 클래스가있는 것이 가장 좋습니다. Brand 클래스를 만들고, BrandList의 이름을 Brands로 변경하고 (참조하는 XML 부분에 더 가까이 다가 가게 함), Brands에 List 를 보유하게합니다. 적절한 주석을 두 클래스 모두에 넣으면 완료해야합니다 (예 :

    @XStreamAlias("brands")
    class Brands {
      @XStreamImplicit
      List<Brand> brand;
    }
    
    @XStreamAlias("brand")
    class Brand {
      String nodeRef;
      String name;
    }
    

    위의 코드는 객체를 XML로 정렬 할 때 완벽하게 작동하지만 XML에서 객체로 언 마샬링 할 때 설명 할 때 실패합니다. 그것이 잘 작동하려면 마샬 러에게 주석을 달았던 수업을 알려줘야합니다.

    <bean name="marshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="autodetectAnnotations" value="true"/>
        <property name="annotatedClasses">
            <array>
                <value>com.kipcast.dataModel.drugs.bean.BrandViewList</value>
                <value>com.kipcast.dataModel.drugs.bean.BrandView</value>
            </array>
        </property>
    </bean>
    

    설치를 확인하는 샘플 프로젝트를 만들었습니다.

  2. ==============================

    2.ArrayList 형식을 사용하여이 문제를 해결했습니다. 목록을 처리하기 위해 가짜 클래스를 사용할 필요가 없습니다. 그것은 (어떤 주석도 사용하지 않고) 다음과 같은 것으로 나를 위해 일했습니다 :

    ArrayList 형식을 사용하여이 문제를 해결했습니다. 목록을 처리하기 위해 가짜 클래스를 사용할 필요가 없습니다. 그것은 (어떤 주석도 사용하지 않고) 다음과 같은 것으로 나를 위해 일했습니다 :

    <bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
            <props>
                <prop key="brands">java.util.ArrayList</prop>
                <prop key="brand">com.kipcast.dataModel.drugs.bean.BrandView</prop>
            </props>
        </property>
    </bean>
    
  3. from https://stackoverflow.com/questions/8312573/spring-restful-client-root-tag-exception by cc-by-sa and MIT license