Yin Shudi
Yin Shudi

Reputation: 227

How to use Jackson with nested Generics?

I use Retrofit and Jackson.There is a POJO like this:

public class QuotationHttpResult<T> {
    private int code;
    private Result result;

    public T getData(){
        return result == null ? null : result.getData();
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public Result getResult() {
        return result;
    }

    public void setResult(Result result) {
        this.result = result;
    }

    class Result{
        private T data;

        public T getData() {
            return data;
        }
    }
} 

The filed data is what I need,sometimes is a POJO,sometimes is a List. When it is a list,jackson just convert data to a LinkedHashMap even though I use the TypeReference: The Json String is :

 {"code": 0,
     "result": {
         "data": [
            {
            "id": "1000",
            "name": "tecent"
            }, 
            {
            "id": "1001",
            "name": "alibaba"
            }
         ]
       }
    }

the convert code:

ObjectMapper mapper = new ObjectMapper();
QuotationHttpResult<List<MyClass>> result = mapper.readValue(json,new TypeReference<QuotationHttpResult<List<MyClass>>>() {});

MyClass is simple:

class MyClass{
    String id;
    String name;
}

I see this question, How to use Jackson with Generics , and everything goes well when I don't nest generics, but how can I do when generics is nested?

Upvotes: 6

Views: 3179

Answers (2)

varren
varren

Reputation: 14731

First of all you should make Result static (more info) or move it out of QuotationHttpResult, so jackson can see it data type. Because of that you will have to make it generic Result<T>. you also have to add getters and setters to your MyClass POJO or add annotations for jackson.

Here is demo:

public class QuotationHttpResult<T> {
    private int code;

    private Result<T> result;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public Result<T> getResult() {
        return result;
    }

    public void setResult(Result<T> result) {
        this.result = result;
    }

    public static class Result<T>{
        private T data;

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }
    }
}

public class MyClass {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public static void main(String[] args) throws IOException {
    String json = " {\"code\": 0,\n" +
            "     \"result\": {\n" +
            "         \"data\": [\n" +
            "            {\n" +
            "            \"id\": \"1000\",\n" +
            "            \"name\": \"tecent\"\n" +
            "            }, \n" +
            "            {\n" +
            "            \"id\": \"1001\",\n" +
            "            \"name\": \"alibaba\"\n" +
            "            }\n" +
            "         ]\n" +
            "       }\n" +
            "    }";
    ObjectMapper mapper = new ObjectMapper();
    QuotationHttpResult<MyClass> result = mapper.readValue(json,new TypeReference<QuotationHttpResult<List<MyClass>>>() {});
    System.out.println(result);
}

Upvotes: 2

kolakao
kolakao

Reputation: 71

You can try with Custom Deserializer for Jackson. I think it's the best way for problematic deserialization...

Upvotes: -1

Related Questions