gson不直接支持序列化@autovalue类或可选的<>字段,但是com.ryanharter.auto.value添加了@autovalue和net。dongliu:gson-java8-datatype adds 可选<>和其他java8类型。
然而,他们一点也不合作。
测试代码:
public class TestOptionalWithAutoValue {
private static final Gson gson = new GsonBuilder().serializeNulls()
// doesnt matter which order these are registered in
.registerTypeAdapterFactory(new GsonJava8TypeAdapterFactory())
.registerTypeAdapterFactory(AutoValueGsonTypeAdapterFactory.create())
.create();
@Test
public void testAutoValueOptionalEmpty() {
AvoTestClass subject = AvoTestClass.create(Optional.empty());
String json = gson.toJson(subject, AvoTestClass.class);
System.out.printf("Json produced = %s%n", json);
AvoTestClass back = gson.fromJson(json, new TypeToken<AvoTestClass>() {}.getType());
assertThat(back).isEqualTo(subject);
}
@Test
public void testAutoValueOptionalFull() {
AvoTestClass subject = AvoTestClass.create(Optional.of("ok"));
String json = gson.toJson(subject, AvoTestClass.class);
System.out.printf("Json produced = '%s'%n", json);
AvoTestClass back = gson.fromJson(json, new TypeToken<AvoTestClass>() {}.getType());
assertThat(back).isEqualTo(subject);
}
}
@AutoValue
public abstract class AvoTestClass {
abstract Optional<String> sval();
public static AvoTestClass create(Optional<String> sval) {
return new AutoValue_AvoTestClass(sval);
}
public static TypeAdapter<AvoTestClass> typeAdapter(Gson gson) {
return new AutoValue_AvoTestClass.GsonTypeAdapter(gson);
}
}
@GsonTypeAdapterFactory
public abstract class AutoValueGsonTypeAdapterFactory implements TypeAdapterFactory {
public static TypeAdapterFactory create() {
return new AutoValueGson_AutoValueGsonTypeAdapterFactory();
}
}
渐变相关性:
annotationProcessor "com.google.auto.value:auto-value:1.7.4"
annotationProcessor("com.ryanharter.auto.value:auto-value-gson-extension:1.3.1")
implementation("com.ryanharter.auto.value:auto-value-gson-runtime:1.3.1")
annotationProcessor("com.ryanharter.auto.value:auto-value-gson-factory:1.3.1")
implementation 'net.dongliu:gson-java8-datatype:1.1.0'
失败原因:
Json produced = {"sval":null}
...
java.lang.NullPointerException: Null sval
...
在序列化时调用net.dongliu.gson.optionaladapter,但在反序列化时不调用。
我想知道是否有一个解决办法,或者如果答案是gson需要有可选的直接支持?
1条答案
按热度按时间lp0sw83n1#
很高兴看到您通过添加更多信息甚至添加测试更新了您的问题!:)这真的很清楚!
我不确定,但是生成的类型适配器没有提到
sval
:我不知道是否有办法配置autovalue或其他生成器中的默认值,但它看起来像一个bug。
如果没有任何方法来解决它(比如说,放弃图书馆开发;等待修复的时间太长;不管怎样),您总是可以自己实现它,但是需要一些运行时成本(基本上这就是gson在数据包对象的后台工作的方式)。这个想法是把工作交给内部人员
RuntimeTypeAdapterFactory
这样它就可以处理一个具体的类,而不是一个抽象类,并根据注册的类型适配器设置所有字段(这样就可以支持java8类型)。这里的代价是反射,因此适配器的工作速度可能比生成的类型适配器慢。另一件事是,如果json属性在json对象中甚至没有遇到,则相应的字段将保留null
. 这需要另一个反序列化后类型适配器。这个解决方案在很大程度上是基于反射的,但是如果生成器不能完成这项工作,它只是一个解决方法(同样,不确定是否可以对它们进行配置,以便不存在这样的问题)。