Estoy tratando de aprender Gson y estoy luchando con la exclusión de campo. Aqui estan mis clases
public class Student {
private Long id;
private String firstName = "Philip";
private String middleName = "J.";
private String initials = "P.F";
private String lastName = "Fry";
private Country country;
private Country countryOfBirth;
}
public class Country {
private Long id;
private String name;
private Object other;
}
Puedo usar GsonBuilder y agregar una ExclusionStrategy para un nombre de campo como firstNameo countrypero parece que no logro excluir propiedades de ciertos campos como country.name.
Usando el método public boolean shouldSkipField(FieldAttributes fa), FieldAttributes no contiene suficiente información para hacer coincidir el campo con un filtro como country.name.
PD: Quiero evitar anotaciones ya que quiero mejorar esto y usar RegEx para filtrar los campos.
Editar : estoy tratando de ver si es posible emular el comportamiento del complemento JSON Struts2
usando Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
Editar: reabrí la pregunta con la siguiente adición:
Agregué un segundo campo con el mismo tipo para aclarar aún más este problema. Básicamente quiero excluir country.namepero no countrOfBirth.name. Tampoco quiero excluir País como tipo. Entonces, los tipos son los mismos, es el lugar real en el gráfico del objeto que quiero señalar y excluir.
fuente

JsonSerializerpara algún tipo,Countryen su caso, para el que luego se aplica yExclusionStrategyque decide qué campos serializar.Respuestas:
Cualquier campo que no desee serializar en general, debe usar el modificador "transitorio", y esto también se aplica a los serializadores json (al menos a algunos que he usado, incluido gson).
Si no desea que el nombre aparezca en el json serializado, dele una palabra clave transitoria, por ejemplo:
Más detalles en la documentación de Gson
fuente
transientlugar de@Exposees que todavía tiene que simular un POJO en su cliente con todos los campos que podrían entrar. En el caso de una API de back-end que podría compartirse entre proyectos, esto podría ser problemático en caso de que Se agregan campos adicionales. Esencialmente es la lista blanca frente a la lista negra de los campos.Nishant proporcionó una buena solución, pero hay una manera más fácil. Simplemente marque los campos deseados con la anotación @Expose, como:
Omita los campos que no desee serializar. Luego, simplemente cree su objeto Gson de esta manera:
fuente
Por lo tanto, desea excluir
firstNameycountry.name. Así es comoExclusionStrategydebería verseSi ve de cerca, devuelve
trueparaStudent.firstNameyCountry.name, que es lo que desea excluir.Necesitas aplicar esto
ExclusionStrategyasí,Esto devuelve:
Supongo que el objeto país se inicializa
id = 91Len la clase de estudiante.Puedes ponerte elegante. Por ejemplo, no desea serializar ningún campo que contenga una cadena de "nombre" en su nombre. Hacer esto:
Esto devolverá:
EDITAR: se agregó más información según lo solicitado.
Esto
ExclusionStrategyhará lo necesario, pero debe pasar "Nombre de campo totalmente calificado". Vea abajo:Aquí es cómo podemos usarlo genéricamente.
Vuelve:
fuente
country.nameestrategia de exclusión que pueda tomar una cadena como y solo excluir el camponamecuando se serializa el campocountry. Debe ser lo suficientemente genérico como para aplicarse a cada clase que tenga una propiedad denominada country de la clase Country. No quiero crear una estrategia de exclusión para cada claseDespués de leer todas las respuestas disponibles, descubrí que lo más flexible, en mi caso, era usar
@Excludeanotaciones personalizadas . Entonces, implementé una estrategia simple para esto (no quería marcar todos los campos usando@Exposeni quería usar lostransientque estaban en conflicto con laSerializableserialización de la aplicación ):Anotación:
Estrategia:
Uso:
fuente
addSerializationExclusionStrategyo enaddDeserializationExclusionStrategylugar desetExclusionStrategiesf.getAnnotation(Exclude.class) != nullaf.getAnnotation(Exclude.class) == nulltransientdebido a las necesidades de otras bibliotecas. ¡Gracias!Me encontré con este problema, en el que tenía una pequeña cantidad de campos que quería excluir solo de la serialización, por lo que desarrollé una solución bastante simple que usa la
@Exposeanotación de Gson con estrategias de exclusión personalizadas.La única forma integrada de usar
@Exposees mediante la configuraciónGsonBuilder.excludeFieldsWithoutExposeAnnotation(), pero como su nombre indica, los campos sin un explícito@Exposese ignoran. Como solo tenía unos pocos campos que quería excluir, encontré la posibilidad de agregar la anotación a cada campo muy engorrosa.Efectivamente quería lo inverso, en el que todo estaba incluido a menos que explícitamente lo
@Exposeexcluyera. Utilicé las siguientes estrategias de exclusión para lograr esto:Ahora puedo excluir fácilmente unos campos con
@Expose(serialize = false)o@Expose(deserialize = false)anotaciones (Nótese que el valor predeterminado para ambos@Exposeatributos estrue). Por supuesto@Expose(serialize = false, deserialize = false), puede usarlo , pero eso se logra de manera más concisa al declarar el campo en sutransientlugar (que todavía tiene efecto con estas estrategias de exclusión personalizadas).fuente
Puedes explorar el árbol json con gson.
Intenta algo como esto:
También puede agregar algunas propiedades:
Probado con gson 2.2.4.
fuente
Se me ocurrió una fábrica de clase para soportar esta funcionalidad. Pase cualquier combinación de campos o clases que desee excluir.
Para usar, cree dos listas (cada una es opcional) y cree su objeto GSON:
fuente
Resolví este problema con anotaciones personalizadas. Esta es mi clase de anotación "SkipSerialisation":
y este es mi GsonBuilder:
Ejemplo:
fuente
@Retention(RetentionPolicy.RUNTIME)a su anotación.O puede decir qué campos no se expondrán con:
en su clase en atributo:
fuente
excludeFieldsWithModifiers()eso.Utilicé esta estrategia: excluí todos los campos que no están marcados con la anotación @SerializedName , es decir:
Vuelve
fuente
Otro enfoque (especialmente útil si necesita tomar una decisión para excluir un campo en tiempo de ejecución) es registrar un TypeAdapter con su instancia de gson. Ejemplo a continuación:
En el siguiente caso, el servidor esperaría uno de los dos valores, pero dado que ambos eran ints, entonces gson los serializaría a ambos. Mi objetivo era omitir cualquier valor que sea cero (o menos) del json que se publica en el servidor.
fuente
La
@Transientanotación de Kotlin también hace el truco aparentemente.Salida:
fuente
Estoy trabajando simplemente poniendo la
@Exposeanotación, aquí mi versión que usoEn
Modelclase:En la
Adapterclase:fuente
Tengo la versión de Kotlin
y cómo puede agregar esto a Retrofit GSONConverterFactory:
fuente
Esto es lo que siempre uso:
El comportamiento predeterminado implementado en Gson es que los campos de objetos nulos se ignoran.
Significa que el objeto Gson no serializa campos con valores nulos a JSON. Si un campo en un objeto Java es nulo, Gson lo excluye.
Puede usar esta función para convertir algún objeto en nulo o bien configurado por usted mismo
fuente