gpt4 book ai didi

java - 使用 Gson,如何序列化映射中的空值而不是其他类中的空值?

转载 作者:行者123 更新时间:2023-11-30 05:25:22 25 4
gpt4 key购买 nike

使用 Gson,我希望能够序列化 Map 中的空值,但不能序列化其他类中的空值。也就是说,如果我有这样的类(class):

public class Foo {
@SerializedName("bar")
Bar bar;

@SerializedName("my_map")
Map<String, Object> myMap;
}

如果 bar 字段为 null 并且 myMap 包含一个条目 "key"-> null,我希望生成的 JSON 字符串为:

{
"my_map": {
"key": null,
}
}

但是,我需要它以非常通用的方式工作:我有很多具有复杂层次结构的类,并且类和容器可能是深层嵌套的。

我尝试过以下方法:

  • 使用Gson gson = new GsonBuilder().serializeNulls().create()。这不起作用,因为它会序列化所有空值。

  • 使用TypeAdapterFactory。这几乎可以工作,但我找不到一种方法来重用 Gson 的默认 MapTypeAdapter 和序列化上下文,其中 serializeNulls = trueMapTypeAdapterfinal 所以我不能子类化它。我不想从头开始编写 TypeAdapter 来序列化映射。

我觉得我缺少一个简单的解决方案。任何帮助表示赞赏。

最佳答案

您需要注意,我们可以直接在 com.google.gson.stream.JsonWriter 实例上设置 SerializeNulls 功能。因此,让我们实现自定义 com.google.gson.TypeAdapterFactory,它始终强制为 Map 实例提供此功能:

class ForceNullsForMapTypeAdapterFactory implements TypeAdapterFactory {

public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (Map.class.isAssignableFrom(type.getRawType())) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
return createCustomTypeAdapter(delegate);
}

return null;
}

private <T> TypeAdapter<T> createCustomTypeAdapter(TypeAdapter<T> delegate) {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
final boolean serializeNulls = out.getSerializeNulls();
try {
out.setSerializeNulls(true);
delegate.write(out, value);
} finally {
out.setSerializeNulls(serializeNulls);
}
}

@Override
public T read(JsonReader in) throws IOException {
return delegate.read(in);
}
};
}
}

简单用法:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class GsonApp {
public static void main(String[] args) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("nullKey", null);
map.put("other", "Not Null!");

Foo foo = new Foo();
foo.setMyMap(map);

Gson gson = new GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapterFactory(new ForceNullsForMapTypeAdapterFactory())
.create();
System.out.println(gson.toJson(foo));
}
}

上面的代码打印:

{
"my_map": {
"nullKey": null,
"other": "Not Null!"
}
}

关于java - 使用 Gson,如何序列化映射中的空值而不是其他类中的空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58782291/

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