Jak powiedzieć Jacksonowi, aby ignorował pole podczas serializacji, jeśli jego wartość jest zerowa?


687

W jaki sposób Jackson można skonfigurować tak, aby ignorował wartość pola podczas serializacji, jeśli wartość tego pola jest równa null.

Na przykład:

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

Odpowiedzi:


1102

Aby wyłączyć serializowanie właściwości z wartościami zerowymi przy użyciu Jackson> 2.0, możesz skonfigurować ObjectMapperbezpośrednio lub skorzystać z @JsonIncludeadnotacji:

mapper.setSerializationInclusion(Include.NON_NULL);

lub:

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

Alternatywnie można użyć @JsonIncludew module pobierającym, aby atrybut był wyświetlany, jeśli wartość nie jest równa null.

Bardziej kompletny przykład jest dostępny w mojej odpowiedzi na temat sposobu zapobiegania serializacji wartości pustych w Mapie i zerowych pól w fasoli przez Jackson .


81
w przypadku mojego projektu zadziałało @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL):; jakoś twoja adnotacja nie była dostępna.
Emmanuel Touzery,

13
Interfejs API zmienił się nieco w wersji 2.0.
Programista Bruce

11
@ProgrammerBruce -1 odpowiednio zmień odpowiedź, ponieważ wiesz o zmianie.
Martin Asenov

19
Tak, właśnie potwierdziłem, że @JsonIncludenotacja nie działa, ale działa to jak urok: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) (Używam Jacksona 1.9.12 z wiosną 3.2.2.)
gstroup

17
@MartinAsenov - odpowiedź pokazuje najnowszy API; zmieniono go ze @JsonSerializeskładni na @JsonInclude. Starsza składnia jest przestarzała.
Logan Pickup

128

W przypadku Jackson> 1.9.11 i <2.x użyj @JsonSerializeadnotacji, aby to zrobić:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)


10
Obecnie (Jackson 2.x) to podejście jest przestarzałe.
rustyx

39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK

3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)nie działa wartości zerowe są serializowane.
herau

1
Jest przestarzałe, ale jeśli chcesz zachować stare rzeczy, ta odpowiedź jest w porządku! więc dziękuję @WTK :)
DominikAngerer

Na marginesie, Jackson 1.9.12 jest standardem w WebSphere 8.5, mam nadzieję, że ta informacja pozwoli zaoszczędzić komuś dużo czasu, zanim to
zrozumiałem

122

Aby rozwinąć inne odpowiedzi - jeśli chcesz kontrolować pomijanie wartości pustych dla poszczególnych pól, dodaj adnotację do danego pola (lub alternatywnie adnotację „getter” pola).

przykład - tutaj fieldOnezostanie odrzucony z json tylko, jeśli jest pusty. fieldTwozawsze będzie uwzględniony, niezależnie od tego, czy jest pusty.

public class Foo {

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

    private String fieldTwo;
}

Aby domyślnie pominąć wszystkie wartości null w klasie, należy opisać klasę. W razie potrzeby można nadal używać adnotacji dla pól / getterów.

przykład - tutaj fieldOnei fieldTwozostaną odrzucone z json, jeśli są odpowiednio null, ponieważ jest to ustawienie domyślne ustawione przez adnotację klasy. fieldThreezastąpi to ustawienie domyślne i zawsze zostanie uwzględnione, z uwagi na adnotację w polu.

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

    private String fieldOne;

    private String fieldTwo;

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

AKTUALIZACJA

Powyższe dotyczy Jackson 2 . W przypadku wcześniejszych wersji Jacksona musisz użyć:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

zamiast

@JsonInclude(JsonInclude.Include.NON_NULL)

Jeśli ta aktualizacja jest przydatna, proszę głosować za odpowiedzią ZiglioUK poniżej, wskazywała ona na nowszą adnotację Jackson 2 na długo przed zaktualizowaniem mojej odpowiedzi, aby z niej skorzystać!


czy adnotacja na polu nie powinna ZAWSZE być nadpisywana?
Abhinav Vishak

@AbhinavVishak masz rację - dzięki! To była literówka kopiuj-wklej, kiedy zaktualizowałem odpowiedź, aby użyć Jackson 2. Edytowane.
davnicwil

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) jest przestarzała
Yar

1
@ Tak, to jest przestarzałe w Jackson 2.x. Stwierdziłem, że musisz tego używać tylko we wcześniejszych wersjach Jacksona, gdzie nie tylko nie jest on przestarzały, jest to jedyna opcja.
davnicwil

60

W Jackson 2.x użyj:

@JsonInclude(JsonInclude.Include.NON_NULL)

jest to do umieszczenia na polu.
AMS

1
@ams, ta adnotacja powinna zapakować klasę
Edgard Leal

Czy możesz również podać w pełni kwalifikowaną nazwę? Jackson ma wiele adnotacji o tej samej nazwie i innym pakiecie, więc jest to niejednoznaczne.
Vince

czy mówisz, że w Jackson jest wiele adnotacji @JsonInclude? Nie mam pojęcia. Jaka powinna być zatem pełna nazwa? edytuj odpowiedź
ZiglioUK

Pomylenie nazw jest najprawdopodobniej spowodowane tym, że Jackson 1.x i 2.x używają różnych pakietów Java do wszystkiego, aby uniknąć konfliktów modułów ładujących klasy (wrt niekompatybilne wersje klas). Ponieważ ta odpowiedź dotyczy wersji 2.x, pakietem adnotacji będzie com.fasterxml.jackson.annotation- Jackson 1.xorg.codehaus.jackson.annoation
StaxMan

39

Możesz użyć następującej konfiguracji mapowania:

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

Od wersji 2.5 możesz:

mapper.setSerializationInclusion(Include.NON_NULL);

3
Ponieważ jest to przestarzałe w 1.9, należy użyć mapper.getSerializationConfig (). WithSerializationInclusion (JsonSerialize.Inclusion.NON_NULL);
Asa

7
.. lub bezpośrednio: mapper.setSerializationInclusion (NON_NULL);
Asa

@ruslan: Prawdopodobnie dlatego, że dokumentacja getSerializationConfig() mówi: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

W przypadku wersji 2.5.4mapper.setSerializationInclusion(Include.NON_NULL);
Arturo Volpe,


12

w moim przypadku

@JsonInclude(Include.NON_EMPTY)

sprawiło, że zadziałało.


2
NON_EMPTY subtelnie różni się od NON_NULL - zignoruje wartości zerowe, to prawda, ale również zignoruje wartości uważane za puste, co może nie być pożądanym zachowaniem. Zobacz javadocs Jacksona, aby uzyskać więcej informacji
davnicwil

podoba mi się ta odpowiedź, ponieważ zwracanie Opcjonalne z rzeczy, które są naprawdę opcjonalne, jest dobrym pomysłem, a po prostu NON_NULL dostaniesz coś w rodzaju { }wartości zerowej, która bez sensu przenosi idiom Java do konsumenta. to samo z AtomicReference - konsument nie dba o to, jak deweloper zdecydował się na bezpieczeństwo wątków na wewnętrznej reprezentacji odpowiedzi.
Lucas Ross,

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

powinno działać.

Include.NON_EMPTYwskazuje, że właściwość jest serializowana, jeśli jej wartość nie jest równa null i nie jest pusta. Include.NON_NULLwskazuje, że właściwość jest serializowana, jeśli jej wartość nie jest równa null.


2
JsonInclude.Include.NON_EMPTY- wystarczy, ponieważ dotyczy przypadku NOT_NULL
Ilya Buziuk

5

Jeśli chcesz dodać tę regułę do wszystkich modeli w Jackson 2.6+, użyj:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);


5

Działa to w Spring boot 2.0.3+ i Jackson 2.0+

import com.fasterxml.jackson.annotation.JsonInclude;

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

1
To samo @JsonInclude(JsonInclude.Include.NON_NULL)działało dla mnie w Spring Boot 2.1.2 i Jackson Adnotacje 2.9.0
Manasouza

@manasouza Tak, zachowali spójność wszystkich aktualizacji.
Deva


2

Martwiło mnie to od dłuższego czasu i w końcu znalazłem problem. Przyczyną tego problemu był niewłaściwy import. Wcześniej używałem

com.fasterxml.jackson.databind.annotation.JsonSerialize

Który był przestarzały. Po prostu zastąp import przez

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

i użyj go jako

@JsonSerialize(include=Inclusion.NON_NULL)

2

Konfiguracja globalna, jeśli korzystasz z 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;
    }

}

Ustawienie serializacjiInclusion nie dodaje jednego do drugiego. public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; Należy zastosować większy promień wyliczenia włączenia. np. NON_ABSENT obejmuje NON_NULL, a NON_EMPTY obejmuje oba. Tak więc powinien to być builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); tylko dokument
JacksonInclude

2

Jeśli próbujesz serializować listę obiektów, a jeden z nich ma wartość NULL, skończysz, włączając element NULL w JSON, nawet jeśli

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

spowoduje:

[{myObject},null]

aby to uzyskać:

[{myObject}]

można zrobić coś takiego:

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

WSKAZÓWKA: Jeśli korzystasz z DropWizard, możesz odzyskać dane ObjectMapperużywane przez Jersey za pomocąenvironment.getObjectMapper()


1

Mamy wiele odpowiedzi na to pytanie. Ta odpowiedź może być pomocna w niektórych scenariuszach. Jeśli chcesz zignorować wartości zerowe, możesz użyć NOT_NULL na poziomie klasy. jak poniżej

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

Czasami może być konieczne zignorowanie pustych wartości, na przykład zainicjowanie tablicy tablicowej, ale na tej liście nie ma żadnych elementów. W tym czasie użycie adnotacji NOT_EMPTY w celu zignorowania pustych pól wartości

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

0

Jackson 2.x + użycie

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

.withSerializationInclusion(JsonInclude.Include.NON_NULL)zamiast tego prawda?
herau

Dzięki za zwrócenie na to uwagi, powstrzymam się od aktualizacji :-(
ZiglioUK

@ruslan: Prawdopodobnie dlatego, że dokumentacja getSerializationConfig()mówi: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

Musisz także zmienić swoje podejście, używając Map myVariable zgodnie z opisem w dokumentacji, aby wyeliminować wartości 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

Przypadek pierwszy

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

Przypadek drugi

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

Jeśli someStringma wartość null, zostanie zignorowany w obu przypadkach. Jeśli someStringjest „”, można to zignorować tylko w przypadku drugim.

To samo dla List = nulllubList.size() = 0

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.