Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Jackson's TypeReference with generics?

For json mapping I use the following method:

public static <T> T mapJsonToObject(String json, T dtoClass) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(json, new TypeReference<RestResponse<UserDto>>() {
    });
}

And UserDto looks like this:

@JsonIgnoreProperties(ignoreUnknown = true)
public class UserDto {

    @JsonProperty("items")
    private List<User> userList;

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
}

I want to improve this method of mapping without being attached to a UserDto class, and replacing it with a generic.

Is it possible? And How?

Thanks.

like image 216
Mark Korzhov Avatar asked Jan 03 '16 15:01

Mark Korzhov


2 Answers

TypeReference requires you to specify parameters statically, not dynamically, so it does not work if you need to further parameterize types.

What I think you need is JavaType: you can build instances dynamically by using TypeFactory. You get an instance of TypeFactory via ObjectMapper.getTypeFactory(). You can also construct JavaType instances from simple Class as well as TypeReference.

like image 129
StaxMan Avatar answered Nov 14 '22 23:11

StaxMan


One approach will be to define a Jackson JavaType representing a list of items of type clazz. You still need to have access to the class of the generic parameter at runtime. The usual approach is something like

<T> class XX { XX(Class<T> clazz, ...) ... } 

to pass the class of the generic parameter into the generic class at construction.

Upon access to the Class clazz variable you can construct a Jackson JavaType representing, for example, a list of items of class clazz with the following statement.

JavaType itemType = mapper.getTypeFactory().constructCollectionType(List.class, clazz);

I hope it helped. I am using this approach in my own code.

like image 37
Marcel Baumann Avatar answered Nov 15 '22 00:11

Marcel Baumann