gson:将null视为空String

时间:2022-11-13 19:54:32

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的页面上打开了一个问题;希望它能在下一个版本上得到修复。