Tengo un objeto para serializar utilizando Gson
:
class User {
String firstname;
String lastname;
JsonElement opaqueData;
}
En el plano objeto superior, quiero Gson
hacer caso omiso de null
los campos (por ejemplo, si lastname
es null
, no debe ser serializado).
Pero en el campo opaqueData
, quiero null
s para ser serializados, ya que se supone que es un bloque de datos opaco. Así, utilizando new GsonBuilder().serializeNulls().create().toJson(user)
no funcionaría.
Pero @JsonAdapter
no funciona bien
class User {
String firstname;
String lastname;
@JsonAdapter(NullAdapter.class)
JsonElement opaqueData;
}
class NullAdapter extends TypeAdapter<JsonElement> {
@Override
public void write(JsonWriter out, JsonElement value) throws IOException {
out.jsonValue(new GsonBuilder().serializeNulls().create().toJson(value));
}
@Override
public JsonElement read(JsonReader in) throws IOException {
// TODO Auto-generated method stub
return null;
}
}
Parece ser que el adaptador es ignorado por Gson.
¿Es este comportamiento esperado? ¿Cómo puede hacer que esto suceda, sin crear un adaptador para toda la clase de usuario a continuación manualmente serializar cada campo?
Gson
no se molesta en adaptar su tipo de datos interna JsonElement
. No sé si hay algún punto en el puesto JsonElement
especie es el resultado adaptado.
Tener una mirada al código fuente de Gson se puede ver hay dos métodos de nivel superior:
Para cualquier objeto
public String toJson(Object src) {
if (src == null) {
return toJson(JsonNull.INSTANCE);
}
return toJson(src, src.getClass());
}
Creo que es obvio sin copiar el resto del código que el método anterior se ha de buscar y establecer de adaptadores (y consulta de las fábricas adaptador) en su ruta de ejecución. Pero entonces también hay un método similar:
para JsonElement
public String toJson(JsonElement jsonElement) {
StringWriter writer = new StringWriter();
toJson(jsonElement, writer);
return writer.toString();
}
y por esa ruta de ejecución no hay quien ni establecer ningún adaptador que JsonElement
no está destinado a ser adaptado más.
Así que cuando Gson
golpea cualquier JsonElement
sólo serializa ti como cadena con formato y no se puede afectar en ese wiht ningún adaptador.
Si realmente necesita para serializar algo así como que tal vez usted podría hacer una clase contenedora para el JsonElement
, algo así como:
public class JsonElementWrapper {
public JsonElement jsonElement;
}
y ajustar su TypeAdapter
adaptar dicho a `null``or valor real.