Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Status"

Tags:

java

xml

jackson

I am receiving following error message, I have Status class but it is not being recognized. I've got no idea how to proceed and could not find an answer online.

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"])

EventsResponse

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

    .....

Status

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

Response

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

I added following to Status but I am still receiving the same error.

@XmlElement(name = "Status")
@JacksonXmlProperty(localName = "Status")
private Status status;
like image 471
Daniel Newtown Avatar asked Jun 09 '16 09:06

Daniel Newtown


2 Answers

I failed to reconstruct your issue.

I created a test project github here that has Jackson configuration and JAXB annotations that meet your needs.

I added dependencies to jackson-dataformat-xml and woodstox-core-asl as your Stax implementations (in my test project I am using 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 the Jackson2ObjectMapperBuilder to use both Jackson and JAXB annotations. This is a Spring-boot example to convert to Simple Spring-MVC look here

@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;
 }
}

Note the use of

PropertyNamingStrategy.PASCAL_CASE_TO_CAMEL_CASE

it will save you the need to specify alternative naming for first letter capitalization and will require the use for JAXB annotation only for warping and renaming for example my EventsResponse will look like:

@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;
    ...
}
like image 143
Haim Raman Avatar answered Oct 23 '22 20:10

Haim Raman


You have two options, assuming you are using Jackson to deserialize your XML objects. The simplest is to use Jackson's own XML annotations instead of or as well as the JAXB @XmlElement annotations. For example:

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

(The @XmlElement annotation is in the jackson-dataformat-xml package in Maven - the version should match your other Jackson package versions.)

The alternative is to register an AnnotationIntrospector as part of your deserialization chain - ie. (from a unit test):

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

This recognises the @XmlElement annotation. There are more details in this answer if you need to include this as part of a Spring configuration, for example.

(In order to use the JaxbAnnotationIntrospector class, you will need the jackson-module-jaxb-annotation module from Maven.)

like image 20
Matt Pearce Avatar answered Oct 23 '22 19:10

Matt Pearce