Deserializing a Generic Type with Jackson

jiduvah picture jiduvah · Oct 29, 2012 · Viewed 20.8k times · Source

I am trying to make a class that uses the Jackson to deserialize POJO's.

It looks like this...

public class DeserialiserImp<T> implements Deserialiser<T> {

        protected ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public T get(String content, Class clazz) throws IOException {
            return (T) objectMapper.readValue(content, clazz);
        }

        @Override
        public List<T> getList(String content, Class clazz) throws IOException {
            return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, clazz));
        }

    }

I have 2 questions about this implementation.

The first is that I am passing the class type into the methods so the objectmapper knows the type that should deserialize. Is there a better way using generics?

Also in the get method I am casting an object returned from the objectMapper to T. This seems particularly nasty way of doing it as I have to cast T here and then I have to also cast the object type from the method which is calling it.

I am using Roboguice in this project so it would be nice if I could change the type through injection and then annotate the object which the Generic type I need it to return. I read about TypeLiteral and wondering if it could solve this problem?

Answer

Pierre-Henri picture Pierre-Henri · Oct 29, 2012

The first is that I am passing the class type into the methods so the objectmapper knows the type that should deserialize. Is there a better way using generics?

Unfortunately not, and this is because of type erasure.

Also in the get method I am casting an object returned from the objectMapper to T. This seems particularly nasty way of doing it as I have to cast T here and then I have to also cast the object type from the method which is calling it.

Do this instead :

@Override
public T get(String content, Class<T> clazz) throws IOException {
    return objectMapper.readValue(content, clazz);
}

I am using Roboguice in this project so it would be nice if I could change the type through injection and then annotate the object which the Generic type I need it to return. I read about TypeLiteral and wondering if it could solve this problem?

I don't really understand what you want to achieve, but since you need to pass the class anyways, is that still possible ?