xmlmapper usewrapping new jacksonxmlelementwrapper false deserializar java xml jackson

usewrapping - xml to object java



Causado por: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: campo no reconocido "Estado" (2)

Recibo el siguiente mensaje de error, tengo la clase de estado pero no se reconoce. No tengo idea de cómo proceder y no pude encontrar una respuesta en línea.

Error

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "Status" (class com.myproject.ticket.EventsResponse), not marked as ignorable (3 known properties: "events", "status", "page"]) .... Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Status" (class com.myproject.ticket.EventsResponse), not marked as ignorable (3 known properties: "events", "status", "page"])

EventosRespuesta

@XmlRootElement(name = "EventsResponse") @XmlAccessorType(XmlAccessType.FIELD) public class EventsResponse { @XmlElement(name = "Status") private Status status; @XmlElement(name = "Paging") private Page page; @XmlElementWrapper(name="Events") @XmlElement(name = "Event") private List<Event> events; .....

Estado

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Status { @XmlElement(name = "Version") private double version; @XmlElement(name = "TimeStampUtc") private Date timeStampUtc; @XmlElement(name = "Code") private int code; @XmlElement(name = "Message") private String message; @XmlElement(name = "Details") private String details;

Respuesta

<EventsResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Status> <Version>2.0</Version> <TimeStampUtc>2016-06-11T09:32:21</TimeStampUtc> <Code>0</Code> <Message>Success</Message> <Details /> </Status> <Paging> <PageNumber>1</PageNumber> <PageSize>50</PageSize> <PageResultCount>15</PageResultCount> <TotalResultCount>15</TotalResultCount> <TotalPageCount>1</TotalPageCount> </Paging> <Events> <Event>

Agregué el siguiente estado, pero sigo recibiendo el mismo error.

@XmlElement(name = "Status") @JacksonXmlProperty(localName = "Status") private Status status;


No pude reconstruir tu problema.

Creé un proyecto de prueba github aquí que tiene la configuración de Jackson y las anotaciones JAXB que satisfacen tus necesidades.

Agregué dependencias a jackson-dataformat-xml y woodstox-core-asl como las implementaciones de Stax (en mi proyecto de prueba estoy usando Jackson 2.6.6., Spring 4.2.6)

<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.6.6</version> </dependency> <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>woodstox-core-asl</artifactId> <version>4.4.1</version> </dependency>

Configure Jackson2ObjectMapperBuilder para usar las anotaciones Jackson y JAXB. Este es un ejemplo de Spring-boot para convertir a Simple Spring-MVC mira aquí

@SpringBootApplication public class EventAppConfiguration { public static void main(String[] args) { SpringApplication.run(EventAppConfiguration.class, args); } @Bean public Jackson2ObjectMapperBuilder jacksonBuilder() { Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder(); b.indentOutput(true) //Enable Introspects for both Jackson and JAXB annotation .annotationIntrospector(introspector()) //Use CamelCase naming .propertyNamingStrategy(PropertyNamingStrategy.PASCAL_CASE_TO_CAMEL_CASE) .dateFormat(new SimpleDateFormat("yyyy-MM-dd''T''hh:mm:ss")); return b; } @Bean public AnnotationIntrospector introspector(){ AnnotationIntrospector primary = new JacksonAnnotationIntrospector(); AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary); return pair; } }

Tenga en cuenta el uso de

PropertyNamingStrategy.PASCAL_CASE_TO_CAMEL_CASE

le ahorrará la necesidad de especificar nombres alternativos para el uso de mayúsculas en la primera letra y requerirá el uso para la anotación JAXB solo para warping y cambio de nombre; por ejemplo, mi EventsResponse se verá así:

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class EventsResponse { private Status status; @XmlElement(name = "Paging") private Page page; @XmlElementWrapper(name = "Events") @XmlElement(name = "Event") private List<Event> events; ... }


Tienes dos opciones, suponiendo que estés usando Jackson para deserializar tus objetos XML. Lo más simple es usar las propias anotaciones XML de Jackson en lugar de las anotaciones JAXB @XmlElement o tan bien como las @XmlElement . Por ejemplo:

@XmlElement(name = "Status") @JacksonXmlProperty(localName = "Status") private Status status;

(La anotación @XmlElement está en el paquete jackson-dataformat-xml en Maven; la versión debe coincidir con las otras versiones de paquete de Jackson).

La alternativa es registrar un AnnotationIntrospector como parte de su cadena de deserialización, es decir. (a partir de una prueba unitaria):

XmlMapper mapper = new XmlMapper(); AnnotationIntrospector aiJaxb = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); mapper.setAnnotationIntrospector(aiJaxb); // EVENTS_RESPONSE is the incoming XML EventsResponse response = mapper.readValue(EVENTS_RESPONSE, EventsResponse.class);

Esto reconoce la anotación @XmlElement . Hay más detalles en esta respuesta si necesita incluir esto como parte de una configuración de Spring, por ejemplo.

(Para utilizar la clase JaxbAnnotationIntrospector , necesitará el jackson-module-jaxb-annotation de Maven).