skip to Main Content

I had a working REST Client Class using javax.ws.rs.WebTarget, .Client and javax.ws.rs.core.MediaType for a server’s REST service which returns a JSON String. Unfortunately after what I believe were changes in the format of the JSON String I can no longer parse the result into POJOs via WebTarget, instead I get "Error reading entity from input stream" caused by "Can not deserialize instance of myproject.pojo.Entity[] out of START_OBJECT token".

Entries.java:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Entity {

   private String key;

   public Entity() {}

   public String getKey() {
      return key;
   }

   public void setKey(String key) {
      this.key = key;
   }

RestClient.java method for parsing all Entities, where target is an instance of WebTarget:

public Entity[] getEntities() {
   return target.path("entities").request(MediaType.APPLICATION_JSON).get(Entity[].class);
}

When using .get(String.class) instead of the POJO and printing the result to the console I see that I get the JSON text just fine:

{ "elements": [ { "key": "key1", "name": "name1", "someAdditionalInfo": { "info1": "info1", "info2": "info2"} }, {"key:" "key2", etc...} ], "total": 23 }

I’m suspecting the "elements:" prefix and "total" suffix before and after the list to be the cause of all this. I tried using .get(new GenericEntity<List>() {}) but had the same result.

2

Answers


  1. Your JSON contains an object with data in "elements" field and not an array. To parse it, you need to create an object (DTO) that matches your input, for example:

    public class EntityList {
        private Entity[] elements;
        private int total;
        ...
        // (getters, setters)
    }
    

    The important thing here is that the field with data is also named elements so that Jackson deserializer sets this field accordingly from your items.

    This should allow you to get the result as

    target.path("entities")
        .request(MediaType.APPLICATION_JSON)
        .get(EntityList.class)
        .getElements();
    
    Login or Signup to reply.
  2. It looks like the response previously contained just the list of entities, and now that has been given the name "elements". To fix it, you should create a new java class to act as a wrapper for the list of entities:

    @JsonIgnoreProperties(ignoreUnknown = true)
    public class RawResponse {
        private Entity[] elements;
    
        public RawResponse() {}
    
        public Entity[] getElements() {
            return elements;
        }
    
        public void setElements(Entity[] elements) {
            this.elements = elements;
        }
    }
    

    This is assuming you do not care about getting the value of "total". Then change your controller to use the new wrapper class:

    public Entity[] getEntities() {
        return target.path("entities").request(MediaType.APPLICATION_JSON).get(RawResponse.class).getElements();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search