Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 919
Yin Shudi Avatar asked Nov 09 '22 15:11

Yin Shudi


1 Answers

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);
}
like image 140
varren Avatar answered Nov 14 '22 23:11

varren