Tengo problemas para lograr que Jackson deserialice correctamente json en un objeto al llamar a un servicio (específicamente, estamos usando la capacidad de Jackson para usar las anotaciones JAXB ya que también queremos el servicio usar XML). Estoy usando Spring MVC y estoy usando la clase RestTemplate para hacer llamadas al servicio.Problema Deserializando con Jackson utilizando anotaciones JAXB en Spring MVC
Aquí es donde la configuración del MappingJacksonHttpMessageConverter para mi junit:
ObjectMapper jsonMapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
jsonMapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
jsonMapper.getSerializationConfig().setAnnotationIntrospector(introspector);
jsonMapper.getSerializationConfig().setSerializationInclusion(Inclusion.NON_NULL);
MappingJacksonHttpMessageConverter jacksonConverter = new MappingJacksonHttpMessageConverter();
jacksonConverter.setObjectMapper(jsonMapper);
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(jacksonConverter);
template.setMessageConverters(converters);
Y llamar al servicio de este modo:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Accept", "application/json");
HttpEntity<String> requestEntity = new HttpEntity<String>(requestHeaders);
ResponseEntity<NamedSystem> responseEntity = template.exchange(baseURL + "/{NamedSystemId}",
HttpMethod.GET, requestEntity, NamedSystem.class, orgId1);
Mi clase NamedSystem
está configurado de este modo:
@XmlRootElement(name = "NamedSystem", namespace = "http://schemas.abc.workplace.com/NamedSystem")
public class NamedSystem {
private String id;
private String name;
private String description;
private Set<NamedSystemAlias> aliases;
private String href;
@XmlAttribute(required = false, name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlAttribute(required = false, name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlAttribute(required = false, name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@XmlElementWrapper(required = false, name = "aliases", namespace = "http://schemas.abc.workplace.com/NamedSystem")
@XmlElement(required = false, name = "alias", namespace = "http://schemas.abc.workplace.com/NamedSystem")
public Set<NamedSystemAlias> getAliases() {
return aliases;
}
public void setAliases(Set<NamedSystemAlias> aliases) {
this.aliases = aliases;
}
@XmlAttribute(required = true, name = "href")
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
}
Este es el error que resulta:
org.springframework.web.client.ResourceAccessException: I/O error: Unrecognized field "NamedSystem" (Class com.workplace.abc.named.NamedSystem), not marked as ignorable
at [Source: [email protected]9c; line: 1, column: 2]; nested exception is org.codehaus.jackson.map.JsonMappingException: Unrecognized field "NamedSystem" (Class com.workplace.abc.named.NamedSystem), not marked as ignorable
at [Source: [email protected]9c; line: 1, column: 2]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:453)
....
Caused by: org.codehaus.jackson.map.JsonMappingException: Unrecognized field "NamedSystem" (Class com.workplace.abc.named.NamedSystem), not marked as ignorable
at [Source: [email protected]9c; line: 1, column: 2]
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159)
at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:247)
at org.codehaus.jackson.map.deser.StdDeserializer.reportUnknownProperty(StdDeserializer.java:366)
at org.codehaus.jackson.map.deser.StdDeserializer.handleUnknownProperty(StdDeserializer.java:352)
at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:543)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:402)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:287)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1588)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1172)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:132)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:154)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:74)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:619)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:446)
... 32 more
Parece que no reconoce el rootElement 'NamedSystem' para poder deserializar. ¿Cómo lo haría para hacer eso? He visto ejemplos que usan las mismas anotaciones JAXB y funcionan bien, así que no estoy seguro de qué es diferente en mi caso o cómo podría obligarlo a deserializarlo correctamente. Si alguien puede ofrecer ayuda, lo agradecería.
Debo señalar que también he intentado agregar el convertidor de forma muy simple, como: converters.add (nuevo MappingJacksonHttpMessageConverter()); y obtengo el mismo resultado (creo que la forma en que lo configuro en la publicación es innecesario pero no dañino). Debido a algunas depuraciones, estoy casi 100% seguro de que no se trata de la serialización. Es solo que necesito encontrar una manera de hacer que el analizador JSON reconozca a NamedSystem – AHungerArtist
. El problema también podría resolverse si también pudiera deshacerme de la parte de NamedSystem de Json ... – AHungerArtist