简体   繁体   中英

Jackson deserialize generic with unknown property name

I have following JSON . And I am parsing it using Jackson Parser

 {
  "code": 0,
  "response": {
    "pagination": {
        "page": 1,
        "limit": 20,
        "count": 5,
        "pageCount": 1
    },
   "random": [
      ....
     ]
  }
}

Now I have simple POJO classes created for various random object. I expect 3-4 different types of random object. So instead of creating different wrapper classes for different types of 'random' object I created a generic one

public class PaginatedResponse<E> {

   private Pagination pagination;
   private List<E> responseList;

   public Pagination getPagination() {
       return pagination;
   }

   public void setPagination(Pagination pagination) {
       this.pagination = pagination;
   }

   public List<E> getResponseList() {
       return responseList;
   }

   public void setResponseList(List<E> responseList) {
       this.responseList = responseList;
   }
}

Now For mapping it I used,

  JsonNode tree = mapper.readTree(response);
  TypeReference<PaginatedResponse<LocationParent>> ref = new TypeReference<PaginatedResponse<LocationParent>>() {   };
  PaginatedResponse<LocationParent> resp = mapper.convertValue(tree.get("response"), ref);

But i am not able to map responseList . I get the pagination object but the responseList is always null. Now how to dynamically provide property name for responseList .

Please help

What you need for variable value type is handling for polymorphic types. Generic types alone won't help, since deserialization side would not know what type to use.

You can enable polymorphic type handling with annotation @JsonTypeInfo ; but a problem in this particular case is that you want a List of things of arbitrary type -- due to type-erasure, all Java Lists are really just List<Object> ; there is no typing for elements.

If it was me, I would probably sub-class PaginatedResponse and just add @JsonTypeInfo in base class, like:

@JsonTypeInfo(...) // see javadocs for properties needed
public abstract class PaginatedResponse<T> {
  public Pagination pagination;
  // .. and so on
}

public class PaginatedFooResponse<Foo> { }

The reason to use sub-classing here is simply make it possible for deserializer to figure out element type, given type of response object. Response object will have type ( PaginatedFooResposne ), and from that type of elements is available.

Try this::

JSONObject objJSON = JSONObject.fromString("urString");

String code = objJSON.get("code");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM