Я хочу иметь пользовательскую GSON десериализатор таким образом, что всякий раз, когда он десериализации JSON объекта (то есть что-то внутри фигурные скобки { ... }
), он будет искать для $type
узла и десериализацию, используя его встроенные возможности десериализации к этому типу. Если объект $type
не найден, он просто делает то, что он делает.Gson пользовательских сериализация
Так, например, я бы хотел, чтобы это работало:
{
"$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;
}
Призвание: Object customMessage = gson.fromJson(jsonString, Object.class)
.
Так в настоящее время, если я изменю payload
типа к интерфейсу Payload
:
public class CustomMessage {
public Payload payload;
}
Тогда следующий TypeAdapaterFactory
будет делать то, что я хочу:
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());
}
}
Однако, я хотел бы, чтобы работать, когда payload
имеет тип Object
или любой другой тип, и бросает какое-то исключение соответствия типа, если оно не может назначить переменную.
Не могли бы вы рассказать о том, что не работает с вашим решением? –
@DamianWalczak - он работает, чтобы его десериализовать в 'CustomMessage', но на самом деле он не попал в typeadapterfactory для полезной нагрузки ... он просто использует встроенную десериализацию – Cheetah