我在 JavaFX 上下文中使用 Gson 序列化。为了避免在我的序列化 Json 中使用属性样板,我创建了一些自定义序列化器/反序列化器来写入属性的值而不是实际的属性对象,特别是这个通用的 Property<T>
。 :
private static class PropertySerializer implements JsonSerializer<Property<?>> {
@Override
public JsonElement serialize(Property<?> property, Type type, JsonSerializationContext context) {
Object value = property.getValue();
return context.serialize(value);
}
}
private static class PropertyDeserializer implements JsonDeserializer<Property<?>> {
@Override
public Property<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonNull()) {
System.out.println("I am never printed");
}
Type typeParam = ((ParameterizedType) typeOfT).getActualTypeArguments()[0];
Object obj = context.deserialize(json, typeParam);
return new SimpleObjectProperty<>(obj);
}
}
在我偶然发现空值之前,它工作得很好。按照设计,当属性的值为 null(不是属性本身)时,我的序列化程序将写入 null,因为它写入的是值,而不是属性(我使用 Gson.serializeNulls()
使其实际写入它)。
我的问题是,在反序列化时,由于 a Gson bug,我的自定义序列化程序未针对空值调用由 com.google.gson.TreeTypeAdapter
中的这些行引起:
@Override public T read(JsonReader in) throws IOException {
if (deserializer == null) {
return delegate().read(in);
}
JsonElement value = Streams.parse(in);
if (value.isJsonNull()) {
return null; // bypasses my custom deserializer! Why you do dat to me?
}
return deserializer.deserialize(value, typeToken.getType(), gson.deserializationContext);
}
这导致属性本身在反序列化后为 null,而不是包含 null 值的非 null 属性。
他们将错误标记为已修复,因为显然有一个使用 TypeAdapterFactory
的解决方法,但我似乎无法弄清楚该怎么做。看起来我必须手动反序列化对象,但我不知道它的类型所以我不能。 TypeAdapter
方法 read
和 write
不要给我提供 JsonDeserializationContext
我目前的 Gson
,所以我不能依赖它的标准反序列化来获取我的值(我使用自定义反序列化器很容易做到这一点)。
private static class PropertyTypeAdapter extends TypeAdapter<Property<?>> {
@Override
public void write(JsonWriter out, Property<?> value) throws IOException {
Object valueToSerialize = value.getValue();
// how to use standard serialization of my object?
}
@Override
public Property<?> read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
return new SimpleObjectProperty<>(null);
default:
Type typeOfT = ???
Type typeParam = ((ParameterizedType) typeOfT).getActualTypeArguments()[0];
return ???; // how to invoke standard deserialization of my object?
}
}
}
有人知道怎么解决吗?
最佳答案
对于 future 的读者:
我不喜欢我最初在其他答案中实现的解决方案,因此我将其更改为使用 TypeAdapter
而不是自定义反序列化器。
这需要编写更多代码,所以我最终编写了一个轻量级库,专门用于在 JavaFX 上下文中使用 Gson,这样就没有人需要再次编写它:)
这是:FxGson .
关于java - 不为空值调用 Gson 自定义解串器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35260490/