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