2012-02-28 12 views
21

Używam google-gson do serializacji mapy Java w łańcuchu JSON. Zapewnia a builder handles null values:gson: Traktuj null jako pusty Ciąg

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

Problem polega na tym, że wynik jest ciąg null, jak w:

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

a wymagany wynik to:

{"111111111":""} 

mogę zrobić ciąg -replace dla null i "", ale jest to brzydkie i podatne na błędy. Czy istnieje natywna obsługa gsonów do dodawania niestandardowego ciągu znaków zamiast null?

+3

Nota boczna: 'null' jest prawidłową wartością json. Zobacz http://json.org/. –

Odpowiedz

4

Jeśli był to twój typ aplikacji, możesz zarejestrować adapter typu. Ale Gson nie zezwala na zmianę serializowanej formy łańcuchów lub typów pierwotnych.

Najlepiej jest zmienić swoje obiekty Java. Lub poluzować ograniczenie wokół zer.

+2

To wydaje się być [nie bardziej prawdziwe] (http://code.google.com/p/google-gson/issues/detail?id=416) po żądaniu OP. – maaartinus

5

Odpowiedź Google groups

miałem taką samą sytuację. Ta próbka mi pomogła.

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

i używa:

GsonBuilder gb = new GsonBuilder(); 
gb.registerTypeAdapter(String.class, new StringConverter()); 
Gson gson = gb.create(); 
22

W aktualnej wersji gson można to zrobić:

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

Ta odpowiedź rozwiązała moje chociaż –

+0

@avalon to zwróć całe pole tego obiektu chcę tylko to pole, które ma wartość null i istnieje w jsonie, więc jakiekolwiek rozwiązanie dla tego –

37

Powyższa odpowiedź działa dobrze dla serializacji, ale na deserialisation, jeśli istnieje w polu o wartości pustej, Gson je pominie i nie będzie wprowadzać metody deserializacji adaptera typu, dlatego należy zarejestrować w niej TypeAdapterFactory i adapter typu powrotu.

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

Hi @oznus. Z mojego rozumienia, Gson nie będzie parsować Json.Null wartości kluczy. Inicjalizuje on wartość domyślną w klasie POJO. Zamiast dodawać TypeAdapter, można zainicjować zmienną w domyślnym konstruktorze. Proszę, popraw mnie jeśli się mylę. Proszę przeczytać ten https://sites.google.com/site/gson/gson-user-guide #NullObjectSupport –

+0

nie wiem dlaczego, ale to nie działa dla mnie – avalon

+0

Zrobiłem to po prostu z częścią adaptera. AdapterFactory nie jest tutaj potrzebny. –

Powiązane problemy