Come dire a Jackson di ignorare un campo durante la serializzazione se il suo valore è nullo?


687

Come può Jackson essere configurato per ignorare un valore di campo durante la serializzazione se il valore di quel campo è nullo?

Per esempio:

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

Risposte:


1102

Per sopprimere le proprietà di serializzazione con valori null utilizzando Jackson> 2.0, è possibile configurare ObjectMapperdirettamente o utilizzare l' @JsonIncludeannotazione:

mapper.setSerializationInclusion(Include.NON_NULL);

o:

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

In alternativa, è possibile utilizzare @JsonIncludein un getter in modo che l'attributo venga visualizzato se il valore non è null.

Un esempio più completo è disponibile nella mia risposta a Come impedire la serializzazione tramite Jackson di valori null all'interno di una mappa e campi null all'interno di un bean .


81
per il mio progetto, ha funzionato @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL):; in qualche modo la tua annotazione non era disponibile.
Emmanuel Touzery,

13
L'API è cambiata un po 'con la versione 2.0.
Programmatore Bruce,

11
@ProgrammerBruce -1 cambia la risposta di conseguenza poiché sei a conoscenza del cambiamento.
Martin Asenov,

19
Sì, ho appena confermato che la @JsonIncludenotazione non funziona, ma questo funziona come un incantesimo: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) (sto usando Jackson 1.9.12 con Spring 3.2.2.)
gstroup

17
@MartinAsenov - la risposta mostra l'API più recente; è stato modificato dalla @JsonSerializesintassi in @JsonInclude. La sintassi precedente è obsoleta.
Logan Pickup,

128

Con Jackson> 1.9.11 e <2.x usa l' @JsonSerializeannotazione per farlo:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)


10
Oggi (Jackson 2.x) questo approccio è deprecato.
Rustyx,

39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK

3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)non funziona i valori nullable sono serializzati.
herau,

1
È deprecato ma se hai bisogno di mantenere roba vecchia questa risposta va benissimo! quindi grazie @WTK :)
DominikAngerer il

Come nota a margine, Jackson 1.9.12 è standard in WebSphere 8.5, spero che questa informazione salverà qualcun altro un sacco di tempo che mi ci è voluto per capirlo :-)
bakoyaro,

122

Solo per espandere le altre risposte - se è necessario controllare l'omissione di valori null in base al campo, annotare il campo in questione (o in alternativa il "getter" del campo).

esempio: qui fieldOneverrà omesso da json solo se è nullo. fieldTwosarà sempre incluso indipendentemente dal fatto che sia nullo.

public class Foo {

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

    private String fieldTwo;
}

Per omettere tutti i valori null nella classe come impostazione predefinita, annotare la classe. Le annotazioni per campo / getter possono comunque essere utilizzate per sovrascrivere questa impostazione predefinita, se necessario.

esempio - qui fieldOnee fieldTwoverrà omesso da json se sono nulli, rispettivamente, perché questa è l'impostazione predefinita dall'annotazione della classe. fieldThreetuttavia sovrascriverà il valore predefinito e sarà sempre incluso, a causa dell'annotazione sul campo.

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

    private String fieldOne;

    private String fieldTwo;

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

AGGIORNARE

Quanto sopra è per Jackson 2 . Per le versioni precedenti di Jackson è necessario utilizzare:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

invece di

@JsonInclude(JsonInclude.Include.NON_NULL)

Se questo aggiornamento è utile, vota la risposta di ZiglioUK di seguito, ha sottolineato la nuova annotazione di Jackson 2 molto prima che aggiornassi la mia risposta per usarla!


l'annotazione sul campo non dovrebbe essere SEMPRE da sovrascrivere?
Abhinav Vishak,

@AbhinavVishak hai ragione - grazie! È stato un refuso quando ho aggiornato la risposta per utilizzare Jackson 2. Modificato.
davnicwil,

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) è deprecato
Yar

1
@Yar sì, è deprecato in Jackson 2.x. Ho affermato che è necessario utilizzare che solo nelle versioni precedenti di Jackson in cui non solo si non deprecato, è l'unica opzione.
davnicwil,

60

In Jackson 2.x, utilizzare:

@JsonInclude(JsonInclude.Include.NON_NULL)

è questo da mettere sul campo.
am

1
@ams, questa annotazione dovrebbe racchiudere una classe
Edgard Leal

Potresti includere anche il nome completo? Jackson ha più annotazioni con lo stesso nome e un pacchetto diverso, quindi è ambiguo.
Vince l'

stai dicendo che ci sono più annotazioni @JsonInclude a Jackson? Non ne avevo idea. Quale dovrebbe essere il nome completo quindi? sentiti libero di modificare la risposta
ZiglioUK,

La confusione con i nomi è molto probabilmente dovuta a Jackson 1.xe 2.x che utilizzano diversi pacchetti Java per tutto, per evitare conflitti con il caricatore di classi (versioni di classe incompatibili wrt). Poiché questa risposta è per 2.x, il pacchetto per le annotazioni sarebbe com.fasterxml.jackson.annotation- Jackson 1.x avutoorg.codehaus.jackson.annoation
StaxMan

39

È possibile utilizzare la seguente configurazione del mapper:

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

Da 2.5 puoi utilizzare:

mapper.setSerializationInclusion(Include.NON_NULL);

3
Poiché questo è deprecato in 1.9, utilizzare mapper.getSerializationConfig (). WithSerializationInclusion (JsonSerialize.Inclusion.NON_NULL);
Asa,

7
..o direttamente: mapper.setSerializationInclusion (NON_NULL);
Asa,

@ruslan: Probabilmente perché la documentazione 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,

Per 2.5.4 utilizzaremapper.setSerializationInclusion(Include.NON_NULL);
Arturo Volpe il


12

nel mio caso

@JsonInclude(Include.NON_EMPTY)

l'ha fatto funzionare.


2
NON_EMPTY è leggermente diverso da NON_NULL: ignorerà i valori null, è vero, ma ignorerà anche i valori considerati vuoti, che potrebbero non essere il comportamento desiderato. Vedi il javadocs di Jackson per maggiori informazioni
davnicwil,

mi piace questa risposta perché restituire Opzionale da cose che sono veramente opzionali è una buona idea, e con NON_NULL otterrai qualcosa come { }null, che trasferisce inutilmente un linguaggio Java al consumatore. lo stesso con AtomicReference: al consumatore non importa come lo sviluppatore abbia scelto di imporre la sicurezza del thread sulla rappresentazione interna della risposta.
Lucas Ross,

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

dovrebbe funzionare.

Include.NON_EMPTYindica che la proprietà è serializzata se il suo valore non è nullo e non è vuoto. Include.NON_NULLindica che la proprietà è serializzata se il suo valore non è nullo.


2
JsonInclude.Include.NON_EMPTY- è sufficiente poiché copre il caso NOT_NULL
Ilya Buziuk,

5

Se vuoi aggiungere questa regola a tutti i modelli in Jackson 2.6+ usa:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);


5

Funzionerà con Spring boot 2.0.3+ e Jackson 2.0+

import com.fasterxml.jackson.annotation.JsonInclude;

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

1
Lo stesso ha @JsonInclude(JsonInclude.Include.NON_NULL)funzionato per me su Spring boot 2.1.2 e sulle annotazioni di Jackson 2.9.0
manasouza,

@manasouza Sì, hanno mantenuto la coerenza con tutti gli aggiornamenti.
Deva,

3

Per Jackson 2.5 utilizzare:

@JsonInclude(content=Include.NON_NULL)

2

Questo mi ha turbato per un bel po 'di tempo e finalmente ho trovato il problema. Il problema era dovuto a un'importazione errata. In precedenza avevo usato

com.fasterxml.jackson.databind.annotation.JsonSerialize

Che era stato deprecato. Sostituisci l'importazione con

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

e usalo come

@JsonSerialize(include=Inclusion.NON_NULL)

2

Configurazione globale se si utilizza 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;
    }

}

Impostazione della serializzazione L'inclusione non ne aggiunge una sull'altra. public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; Si dovrebbe usare il raggio maggiore di enumerazione dell'inclusione. ad esempio NON_ABSENT include NON_NULL e NON_EMPTY include entrambi. Quindi dovrebbe essere solo il builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); documento di JacksonInclude
Olgun Kaya,

2

Se stai cercando di serializzare un elenco di oggetti e uno di questi è null, finirai per includere l'elemento null in JSON anche con

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

comporterà:

[{myObject},null]

per ottenere questo:

[{myObject}]

si può fare qualcosa del tipo:

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

SUGGERIMENTO: se si utilizza DropWizard è possibile recuperare l' ObjectMapperutilizzo di Jersey medianteenvironment.getObjectMapper()


1

Abbiamo molte risposte a questa domanda. Questa risposta può essere utile in alcuni scenari Se si desidera ignorare i valori null, è possibile utilizzare NOT_NULL a livello di classe. come sotto

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

Alcune volte potrebbe essere necessario ignorare i valori vuoti, come è possibile che tu abbia inizializzato l'arrayList ma non ci sono elementi in quell'elenco. In quel momento, utilizza l'annotazione NOT_EMPTY per ignorare quei campi di valori vuoti

@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)invece giusto?
herau,

Grazie per averlo sottolineato, mi terrò lontano
dall'aggiornamento

@ruslan: Probabilmente perché la documentazione 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

Inoltre, devi cambiare il tuo approccio quando usi Map myVariable come descritto nella documentazione per eliminare i null:

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 due

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

Se someStringè null, verrà ignorato in entrambi i casi. Se someStringè "", viene ignorato solo nel secondo caso.

Lo stesso per List = nulloList.size() = 0

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.