2012-02-28 22 views
21

Yo uso google-gson para serializar un mapa de Java en una cadena JSON. Proporciona a builder handles null values:gson: Tratar nulo como cadena vacía

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

El problema es que el resultado es la cadena null, como en:

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

Y el resultado requerido es:

{"111111111":""} 

que pueda hacer una cadena -sustituir por null y "", pero esto es feo y propenso a errores. ¿Hay un soporte gson nativo para agregar una cadena personalizada en lugar de null?

+3

Nota al margen: 'null' es un valor json válido. Ver http://json.org/. –

Respuesta

4

Si este fuera su tipo de aplicación, podría registrar un adaptador de tipo. Pero Gson no le permite cambiar la forma serializada de cadenas o tipos primitivos.

Su mejor opción es cambiar sus objetos Java. O para aflojar la restricción en torno a los nulos.

+2

Esto parece ser [no más verdadero] (http://code.google.com/p/google-gson/issues/detail?id=416) después de la solicitud de OP. – maaartinus

5

Respuesta de Google groups

que tenía la misma situación. Esta muestra me ayudó.

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

y usos:

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

En la versión actual de GSON se puede hacer eso:

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

Esta respuesta resolvió la mía aunque –

+0

@avalon este campo devuelve todos los de ese objeto. Solo quiero ese campo que sea nulo y exista en json así que cualquier solución para ese –

37

La respuesta anterior funciona bien para la serialización, pero en deserialización, si hay un campo con valor nulo, Gson lo saltará y no ingresará el método de deserialización del adaptador de tipo, por lo tanto, necesita registrar un TypeAdapterFactory y devolver el tipo de adaptador en él.

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

Hola @oznus. Desde mi entendimiento, Gson no analizará Json. Valores nulos para las claves. Inicializará el valor predeterminado en la clase POJO. Por lo tanto, en lugar de agregar un TypeAdapter, puede inicializar la variable en el constructor predeterminado. Por favor, corríjame si estoy equivocado. Por favor, lea este https://sites.google.com/site/gson/gson-user-guide #NullObjectSupport –

+0

no sé por qué, pero no funciona para mí – avalon

+0

lo hice solo con parte adaptadora AdapterFactory no es necesario aquí. –

Cuestiones relacionadas