¿Cómo decirle a Jackson que ignore un campo durante la serialización si su valor es nulo?


687

¿Cómo se puede configurar Jackson para ignorar un valor de campo durante la serialización si el valor de ese campo es nulo?

Por ejemplo:

public class SomeClass {
   // what jackson annotation causes jackson to skip over this value if it is null but will 
   // serialize it otherwise 
   private String someValue; 
}

Respuestas:


1102

Para suprimir las propiedades de serialización con valores nulos usando Jackson> 2.0, puede configurar ObjectMapperdirectamente o hacer uso de la @JsonIncludeanotación:

mapper.setSerializationInclusion(Include.NON_NULL);

o:

@JsonInclude(Include.NON_NULL)
class Foo
{
  String bar;
}

Alternativamente, puede usarlo @JsonIncludeen un captador para que el atributo se muestre si el valor no es nulo.

Un ejemplo más completo está disponible en mi respuesta a Cómo evitar que los valores nulos dentro de un Mapa y los campos nulos dentro de un bean se serialicen a través de Jackson .


81
para mi proyecto, esto funcionó: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL); de alguna manera tu anotación no estaba disponible.
Emmanuel Touzery

13
La API cambió un poco con la versión 2.0.
Programador Bruce

10
@ProgrammerBruce -1 cambia tu respuesta en consecuencia ya que estás al tanto del cambio.
Martin Asenov

19
Sí, acabo de confirmar que la @JsonIncludenotación no funciona, pero esto funciona de @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) maravilla : (Estoy usando Jackson 1.9.12 con Spring 3.2.2.)
gstroup

17
@MartinAsenov: la respuesta muestra la API más reciente; se cambió de la @JsonSerializesintaxis a @JsonInclude. La sintaxis anterior está en desuso.
Logan Pickup

128

Con Jackson> 1.9.11 y <2.x use la @JsonSerializeanotación para hacer eso:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)


10
Hoy en día (Jackson 2.x) este enfoque está en desuso.
rustyx

39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK

3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)no funciona los valores anulables se serializan.
herau

1
Está en desuso, pero si necesita mantener cosas viejas, ¡esta respuesta está totalmente bien! así que gracias @WTK :)
DominikAngerer

Como nota al margen, Jackson 1.9.12 es estándar en WebSphere 8.5, espero que esta información le ahorre a alguien más tiempo que me tomó resolver esto :-)
bakoyaro

122

Solo para ampliar las otras respuestas: si necesita controlar la omisión de valores nulos por campo, anote el campo en cuestión (o, alternativamente, anote el 'captador' del campo).

ejemplo: aquí solo fieldOnese omitirá de json si es nulo. fieldTwosiempre se incluirá independientemente de si es nulo.

public class Foo {

    @JsonInclude(JsonInclude.Include.NON_NULL) 
    private String fieldOne;

    private String fieldTwo;
}

Para omitir todos los valores nulos en la clase por defecto, anote la clase. Las anotaciones por campo / captador todavía se pueden usar para anular este valor predeterminado si es necesario.

ejemplo: aquí fieldOney fieldTwose omitirá de json si son nulos, respectivamente, porque este es el valor predeterminado establecido por la anotación de clase. fieldThreesin embargo, anulará el valor predeterminado y siempre se incluirá, debido a la anotación en el campo.

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Foo {

    private String fieldOne;

    private String fieldTwo;

    @JsonInclude(JsonInclude.Include.ALWAYS)
    private String fieldThree;
}

ACTUALIZAR

Lo anterior es para Jackson 2 . Para versiones anteriores de Jackson necesitas usar:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

en vez de

@JsonInclude(JsonInclude.Include.NON_NULL)

Si esta actualización es útil, vota la respuesta de ZiglioUK a continuación, ¡señaló la nueva anotación Jackson 2 mucho antes de que actualizara mi respuesta para usarla!


¿No debería anularse SIEMPRE la anotación en el campo?
Abhinav Vishak

@AbhinavVishak tienes razón, ¡gracias! Fue un error tipográfico copiar y pegar cuando actualicé la respuesta para usar Jackson 2. Editado.
davnicwil

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) está en desuso
Yar

1
@Yar sí, eso está en desuso en Jackson 2.x. Yo he dicho que es necesario usar que sólo en versiones anteriores de Jackson, donde no sólo se no desuso, es la única opción.
davnicwil

60

En Jackson 2.x, use:

@JsonInclude(JsonInclude.Include.NON_NULL)

es esto para ser colocado en el campo.
enms.

1
@ams, esta anotación debería envolver una clase
Edgard Leal

¿Podría incluir también el nombre completo? Jackson tiene múltiples anotaciones con el mismo nombre y un paquete diferente, por lo que es ambiguo.
Vince

¿Estás diciendo que hay varias anotaciones @JsonInclude en Jackson? No tenía ni idea. ¿Cuál debería ser el nombre completo entonces? no dude en editar la respuesta
ZiglioUK

La confusión con los nombres probablemente se deba a que Jackson 1.xy 2.x utilizan diferentes paquetes de Java para todo, para evitar conflictos con el cargador de clases (versiones de clase incompatibles con wrt). Dado que esta respuesta es para 2.x, el paquete para anotaciones sería com.fasterxml.jackson.annotation: Jackson 1.x teníaorg.codehaus.jackson.annoation
StaxMan el

39

Puede usar la siguiente configuración del mapeador:

mapper.getSerializationConfig().setSerializationInclusion(Inclusion.NON_NULL);

Desde 2.5 puedes usar:

mapper.setSerializationInclusion(Include.NON_NULL);

3
Como esto está en desuso en 1.9, use mapper.getSerializationConfig (). WithSerializationInclusion (JsonSerialize.Inclusion.NON_NULL);
Asa

77
..o directamente: mapper.setSerializationInclusion (NON_NULL);
Asa

@ruslan: Probablemente porque la documentación de getSerializationConfig() dice:Note that since instances are immutable, you can NOT change settings by accessing an instance and calling methods: this will simply create new instance of config object.
Zero3

Para uso 2.5.4mapper.setSerializationInclusion(Include.NON_NULL);
Arturo Volpe


12

en mi caso

@JsonInclude(Include.NON_EMPTY)

Lo hizo funcionar.


2
NON_EMPTY es sutilmente diferente de NON_NULL: ignorará los valores nulos, eso es cierto, pero también ignorará los valores considerados vacíos, que pueden no ser el comportamiento deseado. Ver los Jackson Javadocs para más información
davnicwil

Me gusta esta respuesta porque devolver Opcional de cosas que son realmente opcionales es una buena idea, y con solo NON_NULL obtendría algo como { }nulo, que transfiere sin sentido un idioma de Java al consumidor. lo mismo con AtomicReference: al consumidor no le importa cómo el desarrollador eligió hacer cumplir la seguridad de los hilos en la representación interna de la respuesta.
Lucas Ross

8
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)

Deberia trabajar.

Include.NON_EMPTYindica que la propiedad se serializa si su valor no es nulo y no está vacío. Include.NON_NULLindica que la propiedad se serializa si su valor no es nulo.


2
JsonInclude.Include.NON_EMPTY- es suficiente ya que cubre el caso NOT_NULL
Ilya Buziuk

5

Si desea agregar esta regla a todos los modelos en Jackson 2.6+ use:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);


5

Esto funcionará en Spring boot 2.0.3+ y Jackson 2.0+

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiDTO
{
    // your class variable and 
    // methods
}

1
Eso mismo @JsonInclude(JsonInclude.Include.NON_NULL)funcionó para mí en Spring boot 2.1.2 y las anotaciones de Jackson 2.9.0
manasouza

@manasouza Sí, han mantenido la coherencia en todas las actualizaciones.
Deva

3

Para Jackson 2.5 use:

@JsonInclude(content=Include.NON_NULL)

2

Esto me ha estado preocupando durante bastante tiempo y finalmente encontré el problema. El problema se debió a una importación incorrecta. Anteriormente había estado usando

com.fasterxml.jackson.databind.annotation.JsonSerialize

Que había quedado en desuso. Simplemente reemplace la importación por

import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;

y úsalo como

@JsonSerialize(include=Inclusion.NON_NULL)

2

Configuración global si usa Spring

@Configuration
public class JsonConfigurations {

    @Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        builder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
        builder.failOnUnknownProperties(false);
        return builder;
    }

}

La configuración de serializationInclusion no agrega uno sobre otro. public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; Uno debería usar el radio de enumeración de inclusión mayor. por ejemplo, NON_ABSENT incluye NON_NULL y NON_EMPTY incluye ambos. Por lo tanto, solo debería ser builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); JacksonInclude doc
Olgun Kaya

2

Si está intentando serializar una lista de objetos y uno de ellos es nulo, terminará incluyendo el elemento nulo en el JSON incluso con

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

resultará en:

[{myObject},null]

para obtener esto:

[{myObject}]

uno puede hacer algo como:

mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
        @Override
        public void serialize(Object obj, JsonGenerator jsonGen, SerializerProvider unused)
                throws IOException
        {
            //IGNORES NULL VALUES!
        }
    });

SUGERENCIA: si está utilizando DropWizard, puede recuperar el ObjectMapperque Jersey está utilizandoenvironment.getObjectMapper()


1

Tenemos muchas respuestas a esta pregunta. Esta respuesta puede ser útil en algunos escenarios. Si desea ignorar los valores nulos, puede usar NOT_NULL en el nivel de clase. como a continuación

@JsonInclude(Include.NON_NULL)
class Foo
{
  String bar;
}

Algunas veces es posible que deba ignorar los valores vacíos, como haber inicializado el arrayList, pero no hay elementos en esa lista. En ese momento, use la anotación NOT_EMPTY para ignorar esos campos de valores vacíos

@JsonInclude(Include.NON_EMPTY)
class Foo
{
  String bar;
}

0

Jackson 2.x + uso

mapper.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.NON_NULL);

.withSerializationInclusion(JsonInclude.Include.NON_NULL)en lugar correcto?
herau

Gracias por señalarlo, no
esperaré para

@ruslan: Probablemente porque la documentación de getSerializationConfig()dice:Note that since instances are immutable, you can NOT change settings by accessing an instance and calling methods: this will simply create new instance of config object.
Zero3

0

Además, debe cambiar su enfoque al usar Map myVariable como se describe en la documentación para eliminar los valores nulos:

From documentation:
com.fasterxml.jackson.annotation.JsonInclude

@JacksonAnnotation
@Target(value={ANNOTATION_TYPE, FIELD, METHOD, PARAMETER, TYPE})
@Retention(value=RUNTIME)
Annotation used to indicate when value of the annotated property (when used for a field, method or constructor parameter), or all properties of the annotated class, is to be serialized. Without annotation property values are always included, but by using this annotation one can specify simple exclusion rules to reduce amount of properties to write out.

*Note that the main inclusion criteria (one annotated with value) is checked on Java object level, for the annotated type, and NOT on JSON output -- so even with Include.NON_NULL it is possible that JSON null values are output, if object reference in question is not `null`. An example is java.util.concurrent.atomic.AtomicReference instance constructed to reference null value: such a value would be serialized as JSON null, and not filtered out.

To base inclusion on value of contained value(s), you will typically also need to specify content() annotation; for example, specifying only value as Include.NON_EMPTY for a {link java.util.Map} would exclude Maps with no values, but would include Maps with `null` values. To exclude Map with only `null` value, you would use both annotations like so:
public class Bean {
   @JsonInclude(value=Include.NON_EMPTY, content=Include.NON_NULL)
   public Map<String,String> entries;
}

Similarly you could Maps that only contain "empty" elements, or "non-default" values (see Include.NON_EMPTY and Include.NON_DEFAULT for more details).
In addition to `Map`s, `content` concept is also supported for referential types (like java.util.concurrent.atomic.AtomicReference). Note that `content` is NOT currently (as of Jackson 2.9) supported for arrays or java.util.Collections, but supported may be added in future versions.
Since:
2.0

0

Caso uno

@JsonInclude(JsonInclude.Include.NON_NULL)
private String someString;

Caso dos

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String someString;

Si someStringes nulo, se ignorará en ambos casos. SisomeString es "" solo se ignorará en el caso dos.

Lo mismo para List = nulloList.size() = 0

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.