Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Jackson ObjectMapper.readValue with generic class

how to use Jackson ObjectMapper.readValue with generic class, someone says that need JavaType, but JavaType is also splicing other class, is Jackson can use like gson TypeToken?

my code is like this

    public static void main(String[] args) throws IOException {
    String json = "{\"code\":200,\"msg\":\"success\",\"reqId\":\"d1ef3b76e73b40379f895a3a7f1389e2\",\"cost\":819,\"result\":{\"taskId\":1103,\"taskName\":\"ei_custom_config\",\"jobId\":233455,\"status\":2,\"interrupt\":false,\"pass\":true}}";
    RestResponse<TaskResult> result = get(json);
    System.out.println(result);
    System.out.println(result.getResult().getJobId());
}

public static <T> RestResponse<T> get(String json) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.readValue(json, new TypeReference<RestResponse<T>>() {});
}

and error is

org.example.zk.RestResponse@6fd02e5
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.example.zk.TaskResult
    at org.example.zk.JacksonTest.main(JacksonTest.java:15)
like image 903
hehe Avatar asked Jul 20 '26 13:07

hehe


2 Answers

You need to provide jackson with concrete type information for T. I would suggest using readValue() overload with parameter - JavaType.

Add the class of T as parameter of get() and construct parametric type using it.

public static <T> RestResponse<T> get(String json, Class<T> classOfT) throws IOException {
  ObjectMapper objectMapper = new ObjectMapper();
  JavaType type = TypeFactory.defaultInstance().constructParametricType(RestResponse.class, classOfT);
  return objectMapper.readValue(json, type);
}

Usage:

RestResponse<TaskResult> result = get(json, TaskResult.class);
like image 173
Chaosfire Avatar answered Jul 22 '26 04:07

Chaosfire


We can make T with upper-bound to help infering object type.

public static <T extends TaskResult> RestResponse<T> get(String json) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.readValue(json, new TypeReference<RestResponse<T>>() {});
}

Without type bounduary, RestResponse<T> equals to RestResponse<Object>
We can not new a generic class with T.

like image 24
shanfeng Avatar answered Jul 22 '26 03:07

shanfeng



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!