典型的な Spring MVC プロジェクトで、外部 Web サービス ソースからフェッチされたオブジェクトにアクセスしようとしています。このデータの実際の統合は、実際には (今までは) プロジェクト内での私の役割ではありませんでした。でも壊れてしまったので直さなければなりません。つまり、関連するコードに完全に精通しているわけではありません。
背景
データ
外部 Web サービスから受信した XML データは次のようになります。
<offeredServiceTOes>
<OfferedService deleted="false">
<id>0001_01-u001/igd</id>
<title>Umschlagleistung (001)</title>
<mainType>turnover</mainType>
<services>
<service id="tos5yyeivg">
<title>Umschlag Bahn - Binnenschiff</title>
<mainType>turnover</mainType>
<systemId>RailRiver</systemId>
<meansOfTransport id="motRail">
<title>Bahn</title>
<description>Bahn</description>
<systemId>Rail</systemId>
</meansOfTransport>
<meansOfTransportRel id="motRiver">
<title>Binnenschiff</title>
<description>Binnenschiff</description>
<systemId>River</systemId>
</meansOfTransportRel>
</service>
<service id="tos5yyeiw0">
[...]
</service>
[...]
</services>
[...]
</OfferedService>
[...]
<offeredServiceTOes>
アンマーシャリング
Spring Rest テンプレートを使用するメソッドは次のようになります。
@Override public List<OfferedServiceTO> getOfferedServices() { return restTemplate.getForObject( dataServiceUriTemplate, OfferedServiceTOList.class, OFFERED_SERVICES );
関連する
OfferedServiceTOList
クラス:@XmlRootElement(name="OfferedService") public class OfferedServiceTO { @XmlElement @XmlID public String id; // [...] @XmlElementWrapper(name="services") @XmlElement(name="service") public List<ServiceTO> services; // [...] }
関連
ServiceTO
クラス@XmlRootElement(name="service") public class ServiceTO { // [...] @XmlElement public String title; /[...] @XmlElementWrapper(name="mainServices") @XmlElement(name="service") public List<ServiceTO> mainServices; }
marshaller/unmarshaller xml Bean 構成
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>a.b.beans.ServiceTO</value> <value>a.b.OfferedServiceTO</value> [...] </list> </property> </bean> <bean id="xmlMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <constructor-arg ref="jaxbMarshaller" /> </bean> <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper" ref="jaxbJacksonObjectMapper"/> </bean> <bean id="jaxbJacksonObjectMapper" class="a.b.path.to.extended.jaxb.JaxbJacksonObjectMapper"> </bean> <bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="objectMapper" ref="jaxbJacksonObjectMapper" /> </bean>
そして最後に、上記
path.to.extended.jaxb.JaxbJacksonObjectMapper
は次のとおりです。public class JaxbJacksonObjectMapper extends ObjectMapper { public JaxbJacksonObjectMapper() { final AnnotationIntrospector primary = new JaxbAnnotationIntrospector(); final AnnotationIntrospector secondary = new JacksonAnnotationIntrospector(); AnnotationIntrospector introspector = new AnnotationIntrospector.Pair(primary, secondary); DeserializationConfig deserializationConfig = super.getDeserializationConfig().withAnnotationIntrospector(introspector); DeserializationProblemHandler errorHandler = new DeserializationProblemHandler() { @Override public boolean handleUnknownProperty(DeserializationContext ctxt, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException, JsonProcessingException { //TODO Logging (unbekanntes Input-JSON) ctxt.getParser().skipChildren(); return true; } }; deserializationConfig.addHandler(errorHandler ); super.setDeserializationConfig(deserializationConfig); SerializationConfig serializationConfig = super.getSerializationConfig().withAnnotationIntrospector(introspector); serializationConfig.set(Feature.WRAP_ROOT_VALUE, true); super.setSerializationConfig(serializationConfig); } }
問題
問題は、最初のリストの注釈 が@XmlElementWrapper(name="services") @XmlElement(name="service")
、xml データのラッピングに関して私には問題ないように見えることです。しかし、私はエラーが発生し続けます:
[...] nested exception is org.springframework.web.client.ResourceAccessException: I/O error: Unrecognized field "service" (Class a.b.ServiceTO), not marked as ignorable
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@76d697d9; line: 7, column: 18] (through reference chain: a.b.OfferedServiceTO["services"]->a.b.ServiceTO["service"]); nested exception is org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "service" (Class a.b.ServiceTO), not marked as ignorable
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@76d697d9; line: 7, column: 18] (through reference chain: a.b.OfferedServiceTO["services"]->a.b.ServiceTO["service"])
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
このような同様の関連する質問は、注釈を付けることで修正されました@XmlElementWrapper(name="services")
。しかし、これはすでに存在しています。
提案をいただければ幸いです。ありがとうございました。
-- マーティン