我使用google-gson将Java地图序列化为JSON字符串。它提供了a builder handles null values:
Gson gson = new GsonBuilder().serializeNulls().create();
问题是结果是字符串null
,如:
gson.toJson(categoriesMap));
{"111111111":null}
所需的结果是:
{"111111111":""}
我可以为null
和""
执行字符串替换,但这很难看并且容易出错。是否有本机gson支持添加自定义字符串而不是null
?
答案 0 :(得分:38)
上面的答案适用于序列化,但是在反序列化时,如果有一个空值的字段,Gson会跳过它并且不能输入类型适配器的deserialize方法,因此你需要注册一个TypeAdapterFactory并返回类型适配器。
Gson gson = GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create();
public static class NullStringToEmptyAdapterFactory<T> implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<T> rawType = (Class<T>) type.getRawType();
if (rawType != String.class) {
return null;
}
return (TypeAdapter<T>) new StringAdapter();
}
}
public static class StringAdapter extends TypeAdapter<String> {
public String read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return "";
}
return reader.nextString();
}
public void write(JsonWriter writer, String value) throws IOException {
if (value == null) {
writer.nullValue();
return;
}
writer.value(value);
}
}
答案 1 :(得分:24)
在gson的实际版本中,您可以这样做:
Object instance = c.getConstructor().newInstance();
GsonBuilder gb = new GsonBuilder();
gb.serializeNulls();
Gson gson = gb.create();
String stringJson = gson.toJson(instance);
答案 2 :(得分:7)
我有同样的情况。这个样本帮助了我。
import java.lang.reflect.Type;
public class StringConverter implements JsonSerializer<String>,
JsonDeserializer<String> {
public JsonElement serialize(String src, Type typeOfSrc,
JsonSerializationContext context) {
if ( src == null ) {
return new JsonPrimitive("");
} else {
return new JsonPrimitive(src.toString());
}
}
public String deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
return json.getAsJsonPrimitive().getAsString();
}
}
并使用:
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(String.class, new StringConverter());
Gson gson = gb.create();
答案 3 :(得分:4)
如果这是您的应用程序类型,您可以注册一个类型适配器。但Gson不允许您更改字符串或基本类型的序列化形式。
最好的办法是更改Java对象。或者放宽对空值的限制。
答案 4 :(得分:1)
没有解决方案。我opened an issue at Gson's page;希望它能在下一版本上修复。
答案 5 :(得分:1)
我几乎可以解决相同的问题。 我也创建了issue。
我从lyubomyr-shaydariv得到了这个答案:
我认为,Gson不会因为性能原因和简单性而遗漏缺失值。您可以轻松地实现一个后处理类型适配器,该适配器会将不受影响的空字段设置为默认值可选
基于original answer的代码段,我用sample project编写了unit tests。