gpt4 book ai didi

java - Gson在反序列化对象时忽略null

转载 作者:搜寻专家 更新时间:2023-10-31 08:04:46 25 4
gpt4 key购买 nike

我想在 Java 中反序列化一个包含空值的 json 字符串。我想将该对象反序列化为 Properties 对象。 json 字符串类似于:

{"prop1":null, "propr2":"fancy value"}

当我反序列化时使用

String json = //
new Gson().fromJson(json, Properties.class);

由于 Properties 对象中的 Hastable,我得到一个空指针异常。如何指示 Gson 忽略空值的反序列化?

最佳答案

问题确实是 Gson 的默认适配器试图将 null 放入 Properties 中,这是被禁止的。

要解决这个问题,您可以编写自己的 TypeAdapter对于 Properties。然后,您必须使用 GsonBuilder 创建 Gson 实例,您 registered那种类型的适配器。

下面显示了这样一个适配器的外观。它稍微更严格一些,因为它在序列化期间防止非字符串键和值(Gson 的默认适配器不这样做),因为它们会在反序列化期间引起问题。但是,您可以使用 Gson.getDelegateAdapter​ 替换它并将序列化委托(delegate)给 Gson 的适配器。 .

private static final TypeAdapter<Properties> PROPERTIES_ADAPTER = new TypeAdapter<Properties>() {
@Override
public Properties read(JsonReader in) throws IOException {
in.beginObject();

Properties properties = new Properties();
while (in.hasNext()) {
String name = in.nextName();
JsonToken peeked = in.peek();

// Ignore null values
if (peeked == JsonToken.NULL) {
in.nextNull();
continue;
}
// Allow Json boolean
else if (peeked == JsonToken.BOOLEAN) {
properties.setProperty(name, Boolean.toString(in.nextBoolean()));
}
// Expect string or number
else {
properties.setProperty(name, in.nextString());
}
}

in.endObject();
return properties;
}

private String asString(Object obj) {
if (obj.getClass() != String.class) {
throw new IllegalArgumentException("Properties contains non-String object " + obj);
}
return (String) obj;
}

/*
* Could also delegate to Gson's implementation for serialization.
* However, that would not fail if the Properties contains non-String values,
* which would then cause issues when deserializing the Json again.
*/
@Override
public void write(JsonWriter out, Properties properties) throws IOException {
out.beginObject();

for (Map.Entry<Object, Object> entry : properties.entrySet()) {
// Make sure that key is a String, otherwise properties
// cannot be deserialized again
out.name(asString(entry.getKey()));

Object value = entry.getValue();
// Be lenient and allow Numbers and Booleans as values
if (value instanceof Number) {
out.value((Number) value);
} else if (value instanceof Boolean) {
out.value((Boolean) value);
} else {
// Require that value is a String
out.value(asString(value));
}
}

out.endObject();
}

}.nullSafe(); // Handle null Properties, e.g. `Properties props = null`

public static void main(String[] args) throws IOException {
Gson gson = new GsonBuilder()
// Register the custom type adapter
.registerTypeAdapter(Properties.class, PROPERTIES_ADAPTER)
.create();

String json = "{\"prop1\":true, \"prop2\":\"text\", \"prop3\":null}";
Properties deserialized = gson.fromJson(json, Properties.class);
System.out.println("Deserialized: " + deserialized);

Properties properties = new Properties();
properties.setProperty("prop", "text");
// Discouraged to put non-Strings, but type adapter supports these
properties.put("boolean", true);
properties.put("number", 1234);
System.out.println("Serialized: " + gson.toJson(properties));
}

关于java - Gson在反序列化对象时忽略null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33301036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com