Wie kann man Jackson anweisen, ein Feld während der Serialisierung zu ignorieren, wenn sein Wert null ist?

687

Wie kann Jackson so konfiguriert werden, dass ein Feldwert während der Serialisierung ignoriert wird, wenn der Wert dieses Felds null ist?

Zum Beispiel:

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

Antworten:

1102

Um Serialisierungseigenschaften mit Nullwerten mit Jackson> 2.0 zu unterdrücken, können Sie die ObjectMapperdirekt konfigurieren oder die @JsonIncludeAnmerkung verwenden:

mapper.setSerializationInclusion(Include.NON_NULL);

oder:

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

Alternativ können Sie @JsonIncludein einem Getter verwenden, damit das Attribut angezeigt wird, wenn der Wert nicht null ist.

Ein vollständigeres Beispiel finden Sie in meiner Antwort auf So verhindern Sie, dass Nullwerte in einer Map und Nullfelder in einer Bean über Jackson serialisiert werden .

Programmierer Bruce
quelle
81
für mein Projekt hat das funktioniert : @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL); Irgendwie war deine Anmerkung nicht verfügbar.
Emmanuel Touzery
13
Die API hat sich mit der Version 2.0 etwas geändert.
Programmierer Bruce
10
@ProgrammerBruce -1 Ändern Sie Ihre Antwort entsprechend, da Sie sich der Änderung bewusst sind.
Martin Asenov
19
Ja, ich habe gerade bestätigt, dass die @JsonIncludeNotation nicht funktioniert, aber das funktioniert wie ein Zauber: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) (Ich verwende Jackson 1.9.12 mit Spring 3.2.2.)
Gruppe
17
@MartinAsenov - Die Antwort zeigt die neueste API. Es wurde von der @JsonSerializeSyntax in geändert @JsonInclude. Die ältere Syntax ist veraltet.
Logan Pickup
128

Verwenden Sie bei Jackson> 1.9.11 und <2.x die @JsonSerializeAnnotation, um dies zu tun:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

WTK
quelle
10
Heutzutage (Jackson 2.x) ist dieser Ansatz veraltet.
Rustyx
39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK
3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)funktioniert nicht Nullwerte werden serialisiert.
Herau
1
Es ist veraltet, aber wenn Sie alte Sachen pflegen müssen, ist diese Antwort völlig in Ordnung! Also danke @WTK :)
DominikAngerer
Nebenbei bemerkt, Jackson 1.9.12 ist Standard in WebSphere 8.5. Hoffentlich spart diese Information jemand anderem viel Zeit, die ich
gebraucht
122

Nur um die anderen Antworten zu erweitern: Wenn Sie das Auslassen von Nullwerten pro Feld steuern müssen, kommentieren Sie das betreffende Feld (oder alternativ den 'Getter' des Felds).

Beispiel - hier fieldOnewird nur von json ausgelassen, wenn es null ist. fieldTwowird immer eingeschlossen, unabhängig davon, ob es null ist.

public class Foo {

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

    private String fieldTwo;
}

Kommentieren Sie die Klasse mit Anmerkungen, um standardmäßig alle Nullwerte in der Klasse wegzulassen. Anmerkungen pro Feld / Getter können weiterhin verwendet werden, um diese Standardeinstellung bei Bedarf zu überschreiben.

Beispiel - hier fieldOneund fieldTwowird von json ausgelassen, wenn sie jeweils null sind, da dies der Standard ist, der durch die Klassenanmerkung festgelegt wird. fieldThreeDer Standardwert wird jedoch überschrieben und aufgrund der Anmerkungen im Feld immer berücksichtigt.

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

    private String fieldOne;

    private String fieldTwo;

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

AKTUALISIEREN

Das obige ist für Jackson 2 . Für frühere Versionen von Jackson müssen Sie Folgendes verwenden:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

anstatt

@JsonInclude(JsonInclude.Include.NON_NULL)

Wenn dieses Update nützlich ist, stimmen Sie bitte der Antwort von ZiglioUK unten zu. Es wurde auf die neuere Anmerkung zu Jackson 2 hingewiesen, lange bevor ich meine Antwort aktualisiert habe, um sie zu verwenden!

davnicwil
quelle
Sollte die Anmerkung auf dem Feld nicht IMMER überschrieben werden?
Abhinav Vishak
@AbhinavVishak du hast recht - danke! Es war ein Tippfehler beim Kopieren und Einfügen, als ich die Antwort auf Jackson 2 aktualisierte. Bearbeitet.
Davnicwil
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) ist veraltet
Yar
1
@Yar ja, das ist in Jackson 2.x veraltet. Ich habe angegeben, dass Sie dies nur in früheren Versionen von Jackson verwenden müssen, wo es nicht nur nicht veraltet ist, sondern die einzige Option.
Davnicwil
60

Verwenden Sie in Jackson 2.x:

@JsonInclude(JsonInclude.Include.NON_NULL)
ZiglioUK
quelle
soll dies auf das Feld gelegt werden.
Ams
1
@ams, diese Anmerkung sollte eine Klasse umschließen
Edgard Leal
Könnten Sie auch den vollständig qualifizierten Namen angeben? Jackson hat mehrere Anmerkungen mit demselben Namen und einem anderen Paket, so dass dies nicht eindeutig ist.
Vince
Wollen Sie damit sagen, dass es in Jackson mehrere @ JsonInclude-Anmerkungen gibt? Ich hatte keine Ahnung. Wie sollte der vollqualifizierte Name dann sein? Fühlen Sie sich frei, die Antwort zu bearbeiten
ZiglioUK
Verwechslungen mit Namen sind höchstwahrscheinlich darauf zurückzuführen, dass Jackson 1.x und 2.x für alles unterschiedliche Java-Pakete verwenden, um Konflikte beim Laden von Klassen zu vermeiden (bei inkompatiblen Klassenversionen). Da diese Antwort für 2.x ist, wäre das Paket für Anmerkungen com.fasterxml.jackson.annotation- Jackson 1.x hatteorg.codehaus.jackson.annoation
StaxMan
39

Sie können die folgende Mapper-Konfiguration verwenden:

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

Seit 2.5 können Sie Benutzer:

mapper.setSerializationInclusion(Include.NON_NULL);
Eren Yilmaz
quelle
3
Verwenden Sie mapper.getSerializationConfig (). WithSerializationInclusion (JsonSerialize.Inclusion.NON_NULL), da dies in 1.9 veraltet ist.
Asa
7
..oder direkt: mapper.setSerializationInclusion (NON_NULL);
Asa
@ Ruslan: Wahrscheinlich, weil die Dokumentation von getSerializationConfig() sagt: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
Für 2.5.4 verwendenmapper.setSerializationInclusion(Include.NON_NULL);
Arturo Volpe
12

in meinem Fall

@JsonInclude(Include.NON_EMPTY)

hat es funktioniert.

Alfthan
quelle
2
NON_EMPTY unterscheidet sich geringfügig von NON_NULL - es ignoriert zwar Nullwerte, aber auch Werte, die als leer betrachtet werden, was möglicherweise nicht das gewünschte Verhalten ist. Siehe die Jackson Javadocs für weitere Informationen
Davnicwil
Ich mag diese Antwort, weil es eine gute Idee ist, Optional von Dingen zurückzukehren, die wirklich optional sind, und mit nur NON_NULL würden Sie so etwas wie { }null erhalten, wodurch eine Java-Sprache sinnlos an den Verbraucher übertragen wird. Gleiches gilt für AtomicReference. Dem Verbraucher ist es egal, wie der Entwickler die Thread-Sicherheit für die interne Darstellung der Antwort erzwingt.
Lucas Ross
8
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)

sollte arbeiten.

Include.NON_EMPTYGibt an, dass die Eigenschaft serialisiert wird, wenn ihr Wert nicht null und nicht leer ist. Include.NON_NULLGibt an, dass die Eigenschaft serialisiert wird, wenn ihr Wert nicht null ist.

Neha Gangwar
quelle
2
JsonInclude.Include.NON_EMPTY- ist genug, da es NOT_NULL Fall abdeckt
Ilya Buziuk
5

Wenn Sie diese Regel allen Modellen in Jackson 2.6+ hinzufügen möchten, verwenden Sie:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
Ilia Kurtov
quelle
5

In Spring Boot können Sie den Jackson ObjectMapperdirekt über Eigenschaftendateien anpassen .

Beispiel application.yml:

spring:
  jackson:
    default-property-inclusion: non_null # only include props if non-null

Mögliche Werte sind:

always|non_null|non_absent|non_default|non_empty

Weitere Informationen : https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper

acdcjunior
quelle
5

Dies funktioniert in Spring Boot 2.0.3+ und Jackson 2.0+

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiDTO
{
    // your class variable and 
    // methods
}
Deva
quelle
1
Das gleiche @JsonInclude(JsonInclude.Include.NON_NULL)funktionierte für mich auf Spring Boot 2.1.2 und Jackson Annotations 2.9.0
Manasouza
@manasouza Ja, sie haben die Konsistenz aller Updates beibehalten.
Deva
3

Für Jackson 2.5 verwenden Sie:

@JsonInclude(content=Include.NON_NULL)
Bilal BBB
quelle
2

Das hat mich schon seit einiger Zeit beunruhigt und ich habe das Problem endlich gefunden. Das Problem war auf einen falschen Import zurückzuführen. Früher hatte ich benutzt

com.fasterxml.jackson.databind.annotation.JsonSerialize

Welches war veraltet. Ersetzen Sie einfach den Import durch

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

und benutze es als

@JsonSerialize(include=Inclusion.NON_NULL)
user3443646
quelle
2

Globale Konfiguration, wenn Sie Spring verwenden

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

}
Xelian
quelle
Durch das Festlegen der serializationInclusion werden keine gegenseitig hinzugefügt. public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; };; Man sollte den größeren Radius der Einschlusszählung verwenden. Beispiel: NON_ABSENT enthält NON_NULL und NON_EMPTY enthält beide. Daher sollte es nur builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); JacksonInclude doc sein
Olgun Kaya
2

Wenn Sie versuchen, eine Liste von Objekten zu serialisieren und eines davon null ist, wird das Null-Element sogar mit in den JSON aufgenommen

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

wird darin enden, dass:

[{myObject},null]

um dies zu bekommen:

[{myObject}]

man kann so etwas machen wie:

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

TIPP: Wenn Sie DropWizard verwenden, können Sie ObjectMapperdas von Jersey verwendete abrufenenvironment.getObjectMapper()

user3474985
quelle
1

Wir haben viele Antworten auf diese Frage. Diese Antwort kann in einigen Szenarien hilfreich sein. Wenn Sie die Nullwerte ignorieren möchten, können Sie NOT_NULL auf Klassenebene verwenden. wie nachstehend

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

Manchmal müssen Sie möglicherweise die leeren Werte ignorieren, z. B. wenn Sie die ArrayList initialisiert haben, aber diese Liste enthält keine Elemente. In dieser Zeit verwenden Sie die Annotation NOT_EMPTY, um diese leeren Wertefelder zu ignorieren

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

quelle
0

Jackson 2.x + verwenden

mapper.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.NON_NULL);
mekdev
quelle
.withSerializationInclusion(JsonInclude.Include.NON_NULL)stattdessen richtig?
Herau
Vielen Dank für den Hinweis, dass ich mich vom Upgrade zurückhalten werde :-(
ZiglioUK
@ Ruslan: Wahrscheinlich, weil die Dokumentation von getSerializationConfig()sagt: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

Außerdem müssen Sie Ihren Ansatz ändern, wenn Sie Map myVariable verwenden, wie in der Dokumentation beschrieben, um Nullen zu beseitigen:

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
atom88
quelle
0

Fall eins

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

Fall zwei

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

Wenn someStringnull ist, wird es in beiden Fällen ignoriert. WennsomeString "" ist, wird es nur in Fall zwei ignoriert.

Das gleiche gilt für List = nulloderList.size() = 0

Nguyen Minh Hien
quelle