Reputation: 4100
I'm writing a class that uses Jackson to serialize/deserialize objects. At compile time I don't know which is the type of the objects I will be serializing/deserializing.
I read a couple of articles and questions about the usages of TypeReference
and TypeFactory
, however I'm still having some issues.
My class looks like (removed some irrelevant code):
public class JsonSerializer<T> {
private ObjectMapper objectMapper;
private TypeReference typeReference;
@PostConstruct
public void init() {
objectMapper = new ObjectMapper();
typeReference = new TypeReference<T>(){ };
}
// ...
public Object decode(CachedData cachedData) {
try {
return objectMapper.readValue(cachedData.getData(), typeReference);
} // ...
}
}
And this is the snippet of code I'm using to test this:
public class SerializerTest {
private JsonSerializer<Clazz> serializer;
private ObjectMapper objectMapper = new ObjectMapper();
private static final String CHARSET = "UTF-8";
private Clazz data = generateData(); // creates a simple object
@BeforeMethod
public void beforeMethod() {
serializer = new JsonSerializer<Clazz>();
serializer.init();
}
// ...
public void shouldDecodeDataCorrectly() throws Exception {
CachedData cachedData = new CachedData(0,
objectMapper.writeValueAsString(data).getBytes(CHARSET),
CachedData.MAX_SIZE);
Object object = serializer.decode(cachedData);
assertEquals(data, object);
}
public static class Clazz {
// POJO with getters and setters
}
}
As far as I could understand, using typeReference
should be enough to let know the deserializer that the value read from the byte stream should be put in a Clazz
object. However, the object returned by the decode()
method is still a Map
, which I understand is the default class for deserializing.
I tried also changing the decode()
method to return return objectMapper.readValue(cachedData.getData(), objectMapper.getTypeFactory().constructType(typeReference))
, but I'm getting the same problem.
I'm quite sure it's something regarding the way I pass the type into the serializer, but I haven't been able so far to fix it. Thanks.
Upvotes: 0
Views: 5392
Reputation: 116620
It is not quite clear what exactly you are trying to do: much of the code does not make change. Specifically usage of TypeReference
is wrong: you can not use type variables with it, type must be concrete.
However, perhaps solution is simpler than you thought. If you can keep track of original Class
, just store that (or name from clazz.getName()
), and pass that when deserializing.
Upvotes: 1
Reputation: 7952
Based on the javadoc at http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/type/TypeReference.html here is how I would do it:
Remove the typeReference field from JsonSerializer
Modify the JsonSerializer.decode method to take a type reference as an argument
Pass the type reference as an argument
Object object = transcoder.decode(cachedData, new TypeReference<Clazz>() {});
BTW - "transcoder" should be "serializer"? Typo?
Upvotes: 0
Reputation: 5654
Did you check @JsonTypeInfo ? Please have a look at it's documentation.
Upvotes: 0