Suppose to have an abstract class, say A
, and two non-abstract subclasses, say A1
and A2
. I want to "deserialize" them from a json format by using the GSON library.
E.g. I get an array of A
objects.
int n = ...;
A[] list = new A[n];
A[0] = new A1(....);
A[1] = new A2(....);
...
which someone converted to a JSON string as follows:
String json = (new Gson()).toJson(list);
Finally, if I try to deserialize as follows
A[] deserializedList = (new Gson()).fromJson(json, A[].class);
then I has got an error, since the GSON default deserializer finds an abstract class (i.e. A
) and it is not capable of guessing the subclass type.
How can I solve this?
PS: I read about custom deserializer, but I don't understand how to use them in this case.
Following the Axxiss link, here follows the answer. A custom serializer/deserializer must be provided.
public class AClassAdapter implements JsonSerializer<A>, JsonDeserializer<A> {
@Override
public JsonElement serialize(A src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.add("type", new JsonPrimitive(src.getClass().getSimpleName()));
result.add("properties", context.serialize(src, src.getClass()));
return result;
}
@Override
public A deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String type = jsonObject.get("type").getAsString();
JsonElement element = jsonObject.get("properties");
try {
String fullName = typeOfT.getTypeName();
String packageText = fullName.substring(0, fullName.lastIndexOf(".") + 1);
return context.deserialize(element, Class.forName(packageText + type));
} catch (ClassNotFoundException cnfe) {
throw new JsonParseException("Unknown element type: " + type, cnfe);
}
}
}
Then the serialization is done like follows:
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(A.class, new ATypeAdapter());
String json = gson.create().toJson(list);
and given the json string, the deserialization is:
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(A.class, new ATypeAdapter());
return gson.create().fromJson(json, A[].class);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With