I use google-gson to serialize a Java map into a JSON string. It provides a builder handles null values:
我使用google-gson将Java地图序列化为JSON字符串。它提供了一个构建器处理空值:
Gson gson = new GsonBuilder().serializeNulls().create();
The problem is that the result is the string null
, as in:
问题是结果是字符串null,如:
gson.toJson(categoriesMap));
{"111111111":null}
And the required result is:
并且所需的结果是:
{"111111111":""}
I can do a String-replace for null
and ""
, but this is ugly and prone to errors. Is there a native gson support for adding a custom String instead of null
?
我可以为null和“”执行字符串替换,但这很难看并且容易出错。是否有本机gson支持添加自定义String而不是null?
5 个解决方案
#1
4
If this were your application type, you could register a type adapter. But Gson doesn't allow you to change the serialized form of strings or primitive types.
如果这是您的应用程序类型,您可以注册一个类型适配器。但Gson不允许您更改字符串或基本类型的序列化形式。
Your best bet is to change your Java objects. Or to loosen the restriction around nulls.
最好的办法是更改Java对象。或者放宽零点周围的限制。
#2
37
The above answer works okay for serialisation, but on deserialisation, if there is a field with null value, Gson will skip it and won't enter the deserialize method of the type adapter, therefore you need to register a TypeAdapterFactory and return type adapter in it.
上面的答案适用于序列化,但是在反序列化时,如果有一个空值的字段,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);
}
}
#3
23
In the actual version of gson you can do that:
在gson的实际版本中,您可以这样做:
Object instance = c.getConstructor().newInstance();
GsonBuilder gb = new GsonBuilder();
gb.serializeNulls();
Gson gson = gb.create();
String stringJson = gson.toJson(instance);
#4
5
Answer from Google groups
Google群组的回答
I had the same situation. This sample helped me.
我有同样的情况。这个样本帮助了我。
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();
}
}
And uses:
用途:
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(String.class, new StringConverter());
Gson gson = gb.create();
#5
1
There's no solution. I've opened an issue at Gson's page; Hope it will get fixed on the next version.
没有解决方案。我在Gson的页面上打开了一个问题;希望它能在下一个版本上得到修复。
#1
4
If this were your application type, you could register a type adapter. But Gson doesn't allow you to change the serialized form of strings or primitive types.
如果这是您的应用程序类型,您可以注册一个类型适配器。但Gson不允许您更改字符串或基本类型的序列化形式。
Your best bet is to change your Java objects. Or to loosen the restriction around nulls.
最好的办法是更改Java对象。或者放宽零点周围的限制。
#2
37
The above answer works okay for serialisation, but on deserialisation, if there is a field with null value, Gson will skip it and won't enter the deserialize method of the type adapter, therefore you need to register a TypeAdapterFactory and return type adapter in it.
上面的答案适用于序列化,但是在反序列化时,如果有一个空值的字段,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);
}
}
#3
23
In the actual version of gson you can do that:
在gson的实际版本中,您可以这样做:
Object instance = c.getConstructor().newInstance();
GsonBuilder gb = new GsonBuilder();
gb.serializeNulls();
Gson gson = gb.create();
String stringJson = gson.toJson(instance);
#4
5
Answer from Google groups
Google群组的回答
I had the same situation. This sample helped me.
我有同样的情况。这个样本帮助了我。
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();
}
}
And uses:
用途:
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(String.class, new StringConverter());
Gson gson = gb.create();
#5
1
There's no solution. I've opened an issue at Gson's page; Hope it will get fixed on the next version.
没有解决方案。我在Gson的页面上打开了一个问题;希望它能在下一个版本上得到修复。