Gson未能调用自定义序列化程序



我一直在尝试遵循这里给出的建议,关闭Json中表示的数值的科学表示法。我遇到的问题是,我的自定义序列化程序从未被调用。

我尝试了不同的代码变体,最终得到了:

public class TestExternaliser {
static class SpecialSerializer implements JsonSerializer<Object> {
@Override
public JsonElement serialize(Object x,
Type type,
JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive("xxx");
}
}
public static void main(String... args) {
JsonObject root = new JsonObject();
root.addProperty("String", "String");
root.addProperty("Num", Integer.valueOf(123));
root.addProperty("Bool", Boolean.TRUE);
Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(Object.class, new SpecialSerializer())
.setPrettyPrinting()
.create();
System.out.println(gson.toJson(root));
}
}

如果我正确理解了API,那么这段代码将对所有值使用自定义序列化,因此它应该为所有值生成"xxx",但我一直得到的是:

{
"String": "String",
"Num": 123,
"Bool": true
}

怎么了?

出了什么问题?

由于Gson的设计限制,没有什么问题:不能重写ObjectJsonElement类型的适配器层次结构。

以下是涵盖所有四个对象/数字层次结构和值/JSON树对的测试:

public final class LimitationsTest {
private static final JsonSerializer<Object> defaultJsonSerializer = (src, typeOfSrc, context) -> new JsonPrimitive("xxx");
private static final Gson objectDefaultsGson = new GsonBuilder()
.registerTypeHierarchyAdapter(Object.class, defaultJsonSerializer)
.create();
private static final Gson numberDefaultsGson = new GsonBuilder()
.registerTypeHierarchyAdapter(Number.class, defaultJsonSerializer)
.create();
private static final class Value {
@SerializedName("String")
private String string;
@SerializedName("Num")
private Number num;
@SerializedName("Bool")
private Boolean bool;
}
private static final Object object;
private static final JsonElement jsonElement;
static {
final Value newObject = new Value();
newObject.string = "String";
newObject.num = 123;
newObject.bool = Boolean.TRUE;
object = newObject;
final JsonObject newJsonElement = new JsonObject();
newJsonElement.addProperty("String", "String");
newJsonElement.addProperty("Num", 123);
newJsonElement.addProperty("Bool", Boolean.TRUE);
jsonElement = newJsonElement;
}
@Test
public void testObjectObject() {
Assertions.assertEquals(""xxx"", objectDefaultsGson.toJson(object));
}
@Test
public void testObjectJsonElement() {
Assertions.assertEquals("{"String":"String","Num":123,"Bool":true}", objectDefaultsGson.toJson(jsonElement));
}
@Test
public void testNumberObject() {
Assertions.assertEquals("{"String":"String","Num":"xxx","Bool":true}", numberDefaultsGson.toJson(object));
}
@Test
public void testNumberJsonElement() {
Assertions.assertEquals("{"String":"String","Num":123,"Bool":true}", numberDefaultsGson.toJson(jsonElement));
}
}

简而言之,JsonElement被认为已经序列化,所以您要查找的内容隐藏在testNumberObject中:将Number定义为超类(或者更准确地说是Float/Double),并序列化包含字段的对象,而不是JsonElement。如果必须使用JsonElement;良好的可格式化性";值直接插入Num属性(BigDecimal应该可以正常工作)。


更新1。

@Test
public void testNoScientificNotationForJsonElement() {
final JsonObject newJsonElement = new JsonObject();
newJsonElement.addProperty("a", new BigDecimal(new BigDecimal("1E+10").toPlainString()));
newJsonElement.addProperty("b", new BigDecimal("1E+10") {
@Override
public String toString() {
return toPlainString();
}
});
final Gson gson = new Gson();
Assertions.assertEquals("{"a":10000000000,"b":10000000000}", gson.toJson(newJsonElement));
}

在player、microsoft库和rust-rcon库中,类似的事情发生在我身上。我给你留下链接。

出现此错误是因为您在2.8.6 之前安装了jdk 11或更高版本和gson

https://github.com/microsoft/playwright-java/issues/245#issuecomment-775351308https://github.com/MrGraversen/rust-rcon/pull/2#event-4300625968

解决方案是使用最新版本的gson,尽管该版本是他们使用的版本,但我将其添加到我的POM中,以迫使maven使其他依赖项使用最新的版本。试着看看并告诉我!

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>

试试这个解决方案:D

相关内容

最新更新