2012-02-28 2 views
21

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

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

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

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

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

{"111111111":""} 

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

+3

Сторона примечания: 'null' является допустимым значением json. См. Http://json.org/. –

ответ

4

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

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

+2

После запроса OP это кажется [не более правдой] (http://code.google.com/p/google-gson/issues/detail?id=416). – maaartinus

5

Ответ от Google groups

У меня была такая же ситуация. Этот образец помог мне.

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

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

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

Этот ответ решил мой, хотя –

+0

@avalon это возвращает все поле этого объекта. Я хочу только то поле, которое null и существует в json, поэтому любое решение для этого –

37

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

Привет @oznus. По моему мнению, Gson не разбирает Json.Null значения для ключей. Он инициализирует значение по умолчанию в классе POJO. Поэтому вместо добавления TypeAdapter вы можете просто инициализировать переменную в конструкторе по умолчанию. пожалуйста, поправьте меня, если я ошибаюсь. Пожалуйста, прочтите этот https://sites.google.com/site/gson/gson-user-guide #NullObjectSupport –

+0

Я не знаю, почему, но это не работает для меня – avalon

+0

Я сделал это просто с адаптером. AdapterFactory здесь не нужен. –

Смежные вопросы