web-dev-qa-db-ja.com

gson:nullを空の文字列として扱う

google-gson を使用してJavaマップをJSON文字列にシリアル化します。これは ビルダーはnull値を処理します

Gson gson = new GsonBuilder().serializeNulls().create();

問題は、結果が次のように文字列nullであることです。

gson.toJson(categoriesMap));
{"111111111":null}

そして、必要な結果は次のとおりです。

{"111111111":""}

nullおよび""の文字列置換を実行できますが、これは見苦しく、エラーが発生しやすくなります。 nullの代わりにカスタム文字列を追加するためのネイティブgsonサポートはありますか?

29
Adam Matan

これがアプリケーションタイプである場合、タイプアダプタを登録できます。ただし、Gsonでは、文字列またはプリミティブ型のシリアル化された形式を変更することはできません。

最善の策は、Javaオブジェクトを変更することです。または、nullに関する制限を緩めることです。

5
Jesse Wilson

上記の答えはシリアル化では問題なく動作しますが、逆シリアル化では、null値のフィールドがある場合、Gsonはそれをスキップし、タイプアダプターの逆シリアル化メソッドを入力しないため、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);
    }
}
38
oznus

Gsonの実際のバージョンでは、次のことができます。

    Object instance = c.getConstructor().newInstance();
    GsonBuilder gb = new GsonBuilder(); 
    gb.serializeNulls();
    Gson gson = gb.create(); 
    String stringJson = gson.toJson(instance);
24
Alessio

Googleグループ からの回答

私も同じ状況でした。このサンプルは私を助けてくれました。

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(); 
7
GeX

解決策はありません。 Gsonのページで問題を開いた ;次のバージョンで修正されることを願っています。

1
Adam Matan