I want to have my own GSON deserializer, so whenever it deserializes a JSON object (i.e. anything inside curly braces { ... }), it will look for $typenode and deserialize using the built-in deserialization of this type. If the object is $typenot found, it just does what it does normally.
So, for example, I would like this to work:
{
"$type": "my.package.CustomMessage"
"payload" : {
"$type": "my.package.PayloadMessage",
"key": "value"
}
}
public class CustomMessage {
public Object payload;
}
public class PayloadMessage implements Payload {
public String key;
}
Call: Object customMessage = gson.fromJson(jsonString, Object.class).
So, if I changed the type payloadto an interface payload:
public class CustomMessage {
public Payload payload;
}
Then the following TypeAdapaterFactorywill do what I want:
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
final PojoTypeAdapter thisAdapter = this;
public T read(JsonReader reader) throws IOException {
JsonElement jsonElement = (JsonElement)elementAdapter.read(reader);
if (!jsonElement.isJsonObject()) {
return delegate.fromJsonTree(jsonElement);
}
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonElement typeElement = jsonObject.get("$type");
if (typeElement == null) {
return delegate.fromJsonTree(jsonElement);
}
try {
return (T) gson.getDelegateAdapter(
thisAdapter,
TypeToken.get(Class.forName(typeElement.getAsString()))).fromJsonTree(jsonElement);
} catch (ClassNotFoundException ex) {
throw new IOException(ex.getMessage());
}
}
However, I would like it to work when it payloadhas a type Objector any type in this regard, and throws some type matching exception if it cannot assign a variable.