使用Gson,如何在地图中序列化null,而在其他类中不能序列化null?

使用Gson,我希望能够在Map中而不是在其他类中序列化null。也就是说,如果我有这样的课程:

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

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

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

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

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

我尝试了以下方法:

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

  • 使用TypeAdapterFactory。这几乎可行,但是我找不到在MapTypeAdapter序列化上下文中重用Gson默认值serializeNulls = true的方法。 MapTypeAdapterfinal,所以我不能对其进行子类化。我不想从头开始编写TypeAdapter来序列化地图。

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

tuzimao1 回答:使用Gson,如何在地图中序列化null,而在其他类中不能序列化null?

您需要注意,我们可以直接在SerializeNulls实例上设置com.google.gson.stream.JsonWriter功能。因此,让我们实现自定义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!"
  }
}
本文链接:https://www.f2er.com/3131746.html

大家都在问