Deserialize Generic class variable
...
how do I tell it to Jackson? Will gson do any better?
The Gson user guide includes a section on exactly what I understand you're trying to accomplish, though that documented example may still be incomplete.
In a blog post, I covered in more detail the solution using Gson 1.7.1. Below is the relevant code example.
Similar (but more involved) solutions using Jackson (1.8.2) are also demonstrated and described in the same blog post. (The different approaches and examples use hundreds of lines of code, so I've omitted reposting them here.)
public class GsonInstanceCreatorForParameterizedTypeDemo
{
public static void main(String[] args)
{
Id<String> id1 = new Id<String>(String.class, 42);
Gson gson = new GsonBuilder().registerTypeAdapter(Id.class,
new IdInstanceCreator()).create();
String json1 = gson.toJson(id1);
System.out.println(json1);
// actual output: {"classOfId":{},"value":42}
// This contradicts what the Gson docs say happens.
// With custom serialization, as described in a
// previous Gson user guide section,
// intended output may be
// {"value":42}
// input: {"value":42}
String json2 = "{\"value\":42}";
Type idOfStringType=new TypeToken<Id<String>>(){}.getType();
Id<String> id1Copy = gson.fromJson(json2, idOfStringType);
System.out.println(id1Copy);
// output: classOfId=class java.lang.String, value=42
Type idOfGsonType = new TypeToken<Id<Gson>>() {}.getType();
Id<Gson> idOfGson = gson.fromJson(json2, idOfGsonType);
System.out.println(idOfGson);
// output: classOfId=class com.google.gson.Gson, value=42
}
}
class Id<T>
{
private final Class<T> classOfId;
private final long value;
public Id(Class<T> classOfId, long value)
{
this.classOfId = classOfId;
this.value = value;
}
@Override
public String toString()
{
return "classOfId=" + classOfId + ", value=" + value;
}
}
class IdInstanceCreator implements InstanceCreator<Id<?>>
{
@SuppressWarnings({ "unchecked", "rawtypes" })
public Id<?> createInstance(Type type)
{
Type[] typeParameters =
((ParameterizedType) type).getActualTypeArguments();
Type idType = typeParameters[0];
return new Id((Class<?>) idType, 0L);
}
}