"Unrecognized field (..) not marked as ignorant", while jaxb unmarshalling xml input

in a typical Spring MVC project, I'm trying to access objects that are retrieved from an external webservice source. The actual integration of this data was not really - until now - my part in the project. But it broke, and I have to fix it. That is: I am not very familiar with the corresponding code.

Background

Data

The XML data received from the external web service is as follows:

<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> 

Unmarshalling

  • A method using Spring Rest patterns is as follows:

     @Override public List<OfferedServiceTO> getOfferedServices() { return restTemplate.getForObject( dataServiceUriTemplate, OfferedServiceTOList.class, OFFERED_SERVICES ); 
  • Associated class OfferedServiceTOList :

     @XmlRootElement(name="OfferedService") public class OfferedServiceTO { @XmlElement @XmlID public String id; // [...] @XmlElementWrapper(name="services") @XmlElement(name="service") public List<ServiceTO> services; // [...] } 
  • Associated ServiceTO Class

     @XmlRootElement(name="service") public class ServiceTO { // [...] @XmlElement public String title; /[...] @XmlElementWrapper(name="mainServices") @XmlElement(name="service") public List<ServiceTO> mainServices; } 
  • Marshaller / unmarshaller xml bean configuration

     <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>abbeans.ServiceTO</value> <value>abOfferedServiceTO</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="abpath.to.extended.jaxb.JaxbJacksonObjectMapper"> </bean> <bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="objectMapper" ref="jaxbJacksonObjectMapper" /> </bean> 
  • And finally, the above 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); } } 

Problem

The problem is that the annotations of the first listing @XmlElementWrapper(name="services") @XmlElement(name="service") look good to me with regards to wrapping XML data. But I keep getting the error:

 [...] nested exception is org.springframework.web.client.ResourceAccessException: I/O error: Unrecognized field "service" (Class abServiceTO), not marked as ignorable at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@76d6 97d9; line: 7, column: 18] (through reference chain: abOfferedServiceTO["services"]->abServiceTO["service"]); nested exception is org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "service" (Class abServiceTO), not marked as ignorable at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@76d6 97d9; line: 7, column: 18] (through reference chain: abOfferedServiceTO["services"]->abServiceTO["service"]) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) 

Related related issues, such as this one , were captured by the @XmlElementWrapper(name="services") annotation. But it is already present.

I would be grateful for any suggestions. Thanks.

- Martin

+4
source share
1 answer

Well, that was easier than expected. A wrapper layer is required in the List box. A closer look at the json doc showed a solution:

In OfferedServiceTO.class

 @XmlElementWrapper(name="services") @XmlElement(name="service") public List<ServiceTO> services; 

need to change to

 @XmlElement(name="services") public ServiceTOList services; 

where ServiceTOList.class should be something like:

 @XmlRootElement(name="service") public class ServiceTOList extends ArrayList<ServiceTO> { public List<ServiceTO> services; } 
+2
source

All Articles