Подтвердить что ты не робот

Gson: обрабатывать null как пустую строку

Я использую google-gson для сериализации карты Java в строку JSON. Он обеспечивает конструктор, обрабатывающий нулевые значения:

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

Проблема заключается в том, что результатом является строка null, как в:

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

И требуемый результат:

{"111111111":""}

Я могу сделать String-replace для null и "", но это уродливо и подвержено ошибкам. Есть ли встроенная поддержка gson для добавления настраиваемой строки вместо null?

4b9b3361

Ответ 1

Если это ваш тип приложения, вы можете зарегистрировать адаптер типа. Но Gson не позволяет изменять сериализованную форму строк или примитивных типов.

Лучше всего изменить свои Java-объекты. Или ослабить ограничение вокруг нулей.

Ответ 2

Вышеприведенный ответ работает нормально для сериализации, но при десериализации, если есть поле с нулевым значением, 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);
    }
}

Ответ 3

В реальной версии gson вы можете сделать это:

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

Ответ 4

Ответа на этот вопрос Группы 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(); 

Ответ 6

Если вы хотите использовать этот подход с полем.

Просто создайте NullStringToEmptyTypeAdapter

class NullStringToEmptyTypeAdapter : TypeAdapter<String>() {

    override fun read(reader: JsonReader): String {
        if (reader.peek() === JsonToken.NULL) {
            reader.nextNull()
            return ""
        }
        return reader.nextString()
    }

    override fun write(writer: JsonWriter, value: String?) {
        if (value == null) {
            writer.nullValue()
            return
        }
        writer.value(value)
    }
}

а затем добавьте аннотацию @JsonAdapter в свое поле

@JsonAdapter(NullStringToEmptyTypeAdapter::class)
val yourField: String