Home > Enterprise >  How to use Jackson ObjectMapper.readValue with generic class
How to use Jackson ObjectMapper.readValue with generic class

Time:06-28

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)

CodePudding user response:

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);

CodePudding user response:

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.

  • Related