-, , , . InstanceCreator, , , . key A, . A ( , , @SerializedName, @Expose, @JsonAdapter...):
final class AJsonDeserializer
implements JsonDeserializer<A> {
private static final JsonDeserializer<A> aJsonDeserializer = new AJsonDeserializer();
private AJsonDeserializer() {
}
static JsonDeserializer<A> getAJsonDeserializer() {
return aJsonDeserializer;
}
@Override
public A deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) {
final JsonObject root = jsonElement.getAsJsonObject();
final A a = new A();
a.key = root.get("key").getAsJsonPrimitive().getAsInt();
a.b = createInnerGson(a.key).fromJson(root.get("b"), B.class);
return a;
}
private static Gson createInnerGson(final int key) {
return new GsonBuilder()
.registerTypeAdapter(B.class, (InstanceCreator<B>) type -> new B(key))
.create();
}
}
, - createInnerGson, Gson Builder, , , Gson ( , ). key . ( , Gson fromJson B (, - gson.merge(someJson, someBInstance))), Gson .)
Deserializer JSON ( , A B , toString):
final Gson gson = new GsonBuilder()
.registerTypeAdapter(A.class, getAJsonDeserializer())
.create();
final A a = gson.fromJson("{\"key\":2048,\"b\":{\"x\":20,\"y\":30}}", A.class);
out.printf("%d, %d\n", a.key, a.b.key);
out.println(a);
:
2048, 2048
A{key=2048, b=B{key=2048, x=20, y=30}}
V2
, ... JsonDeserializer<A> , , A. , "" , Gson. , , , , Gson " " , (), , , (. Gson ).
GsonFactoryJsonDeserializer.java
. Gson . factory: JsonElement Gson, , JsonElement Gson factory (, InstanceCreator, ?). , JSON.
final class GsonFactoryJsonDeserializer
implements JsonDeserializer<Object> {
private final Function<? super JsonElement, Gson> gsonFactory;
private GsonFactoryJsonDeserializer(final Function<? super JsonElement, Gson> gsonFactory) {
this.gsonFactory = gsonFactory;
}
static JsonDeserializer<Object> gsonFactoryJsonDeserializer(final Function<? super JsonElement, Gson> gsonFactory) {
return new GsonFactoryJsonDeserializer(gsonFactory);
}
static <K> JsonDeserializer<Object> gsonFactoryJsonDeserializer(final Function<? super JsonElement, ? extends K> jsonElementToKey,
final Function<? super K, Gson> keyToGson) {
return new GsonFactoryJsonDeserializer(jsonElementToKey.andThen(keyToGson));
}
@Override
public Object deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context)
throws JsonParseException {
final Gson gson = gsonFactory.apply(jsonElement);
return gson.fromJson(jsonElement, type);
}
}
Demo
GsonBuilder factory, GsonBuilder , Gson . gsonFactoryJsonDeserializer : B -. (a.key a.b.key), , .
private static GsonBuilder createDefaultRealGsonBuilder() {
return new GsonBuilder()
;
}
public static void main(final String... args) {
final Gson rootGson = createDefaultRealGsonBuilder()
.registerTypeAdapter(
A.class,
gsonFactoryJsonDeserializer(
jsonElement -> jsonElement.getAsJsonObject()
.get("key")
.getAsJsonPrimitive()
.getAsInt()
,
key -> createDefaultRealGsonBuilder()
.registerTypeAdapter(B.class, (InstanceCreator<B>) type -> new B(key))
.create()
)
)
.create();
final A a = rootGson.fromJson("{\"key\":2048,\"b\":{\"x\":20,\"y\":30}}", A.class);
if ( a.key != a.b.key ) {
throw new AssertionError("NOT working!");
}
out.println("Working.");
}
:
.
, , , , Gson - , .