Como dizer ao Jackson para ignorar um campo durante a serialização se seu valor for nulo?

687

Como Jackson pode ser configurado para ignorar um valor de campo durante a serialização, se o valor desse campo for nulo.

Por exemplo:

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
fonte

Respostas:

1102

Para suprimir propriedades de serialização com valores nulos usando Jackson> 2.0, você pode configurar ObjectMapperdiretamente ou fazer uso da @JsonIncludeanotação:

mapper.setSerializationInclusion(Include.NON_NULL);

ou:

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

Como alternativa, você pode usar @JsonIncludeem um getter para que o atributo seja mostrado se o valor não for nulo.

Um exemplo mais completo está disponível na minha resposta para Como impedir que valores nulos dentro de um mapa e campos nulos dentro de um bean sejam serializados através de Jackson .

Programador Bruce
fonte
81
para o meu projeto, isso funcionou @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL):; de alguma forma, sua anotação não estava disponível.
Emmanuel Touzery
13
A API mudou um pouco com a versão 2.0.
Programador Bruce
10
@ProgrammerBruce -1 altere sua resposta de acordo, pois você está ciente da alteração.
27613 Martin Asenov
19
Sim, eu só confirmou que a @JsonIncludenotação não funcionar, mas isso funciona como um encanto: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) (estou usando Jackson 1.9.12 com Spring 3.2.2.)
gstroup
17
@MartinAsenov - a resposta mostra a API mais recente; foi alterado da @JsonSerializesintaxe para @JsonInclude. A sintaxe mais antiga está obsoleta.
Logan Captura
128

Com Jackson> 1.9.11 e <2.x, use a @JsonSerializeanotação para fazer isso:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

WTK
fonte
10
Atualmente (Jackson 2.x) essa abordagem está obsoleta.
Rustyx #
39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK
3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)não funciona valores anuláveis ​​são serializados.
herau
1
Está obsoleto, mas se você precisar manter coisas antigas, esta resposta é totalmente boa! por isso obrigado @WTK :)
DominikAngerer
Como uma nota lateral, Jackson 1.9.12 é padrão no WebSphere 8.5, espero que esta informação irá poupar alguém muito tempo que me levou a descobrir isso :-)
bakoyaro
122

Apenas para expandir as outras respostas - se você precisar controlar a omissão de valores nulos em uma base por campo, anote o campo em questão (ou, em alternativa, anote o 'getter' do campo).

exemplo - aqui somente fieldOneserá omitido do json se for nulo. fieldTwosempre será incluído, independentemente de ser nulo.

public class Foo {

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

    private String fieldTwo;
}

Para omitir todos os valores nulos na classe como padrão, anote a classe. As anotações por campo / obturador ainda podem ser usadas para substituir esse padrão, se necessário.

exemplo - aqui fieldOnee fieldTwoserá omitido de json se eles forem nulos, respectivamente, porque esse é o padrão definido pela anotação de classe. fieldThreeno entanto, substituirá o padrão e sempre será incluído, devido à anotação no campo.

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

    private String fieldOne;

    private String fieldTwo;

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

ATUALIZAR

O acima é para Jackson 2 . Para versões anteriores do Jackson, você precisa usar:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

ao invés de

@JsonInclude(JsonInclude.Include.NON_NULL)

Se essa atualização for útil, faça o upvote da resposta do ZiglioUK abaixo, ela apontou a anotação mais recente do Jackson 2 muito antes de eu atualizar minha resposta para usá-la!

davnicwil
fonte
a anotação no campo não deve ser SEMPRE substituída?
Abhinav Vishak
@AbhinavVishak você está certo - obrigado! Foi um erro de copiar e colar quando atualizei a resposta para usar o Jackson 2. Editado.
Davnicwil
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) está obsoleto
Yar
1
@ Sim, isso foi preterido no Jackson 2.x. Eu afirmei que você precisa usá-lo apenas nas versões anteriores do Jackson, onde não apenas ele não é preterido, é a única opção.
davnicwil
60

No Jackson 2.x, use:

@JsonInclude(JsonInclude.Include.NON_NULL)
ZiglioUK
fonte
é para ser colocado em campo.
AMS
1
@ams, esta anotação deve Wrapper uma classe
Edgard Leal
Você também pode incluir o nome completo? Jackson possui várias anotações com o mesmo nome e um pacote diferente, portanto isso é ambíguo.
Vince
você está dizendo que existem várias anotações @JsonInclude em Jackson? Eu não fazia ideia. Qual deve ser o nome completo então? sinta-se à vontade para editar a resposta
ZiglioUK
A confusão com nomes provavelmente ocorre devido ao Jackson 1.xe 2.x usarem pacotes Java diferentes para tudo, para evitar conflitos no carregador de classes (versões incompatíveis de classe wrt). Uma vez que esta resposta é para 2.x, pacote para anotações seria com.fasterxml.jackson.annotation- Jackson 1.x tinhaorg.codehaus.jackson.annoation
StaxMan
39

Você pode usar a seguinte configuração do mapeador:

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

Desde o 2.5, você pode usar:

mapper.setSerializationInclusion(Include.NON_NULL);
Eren Yilmaz
fonte
3
Como isso foi preterido na versão 1.9, use mapper.getSerializationConfig (). WithSerializationInclusion (JsonSerialize.Inclusion.NON_NULL);
Asa
7
..ou diretamente: mapper.setSerializationInclusion (NON_NULL);
Asa
@ruslan: Provavelmente porque a documentação getSerializationConfig() diz: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

No meu caso

@JsonInclude(Include.NON_EMPTY)

fez funcionar.

embora
fonte
2
NON_EMPTY é sutilmente diferente de NON_NULL - ele ignorará valores nulos, isso é verdade, mas também ignorará valores considerados vazios, que podem não ser o comportamento desejado. Veja as Jackson javadocs para mais informações
davnicwil
Eu gosto desta resposta porque retornar Opcional a partir de coisas realmente opcionais é uma boa ideia, e com apenas NON_NULL você obteria algo como { }null, que transfere inutilmente um idioma Java para o consumidor. O mesmo acontece com o AtomicReference - o consumidor não se importa com o modo como o desenvolvedor optou por impor a segurança do thread na representação interna da resposta.
Lucas Ross
8
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)

Deveria trabalhar.

Include.NON_EMPTYindica que a propriedade é serializada se seu valor não for nulo e não estiver vazio. Include.NON_NULLindica que a propriedade é serializada se seu valor não for nulo.

Neha Gangwar
fonte
2
JsonInclude.Include.NON_EMPTY- é suficiente, uma vez que cobre caso NOT_NULL
Ilya Buziuk
5

Se você deseja adicionar esta regra a todos os modelos no Jackson 2.6+, use:

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

Se no Spring Boot , você pode personalizar o jackson ObjectMapperdiretamente através dos arquivos de propriedades.

Exemplo application.yml:

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

Os valores possíveis são:

always|non_null|non_absent|non_default|non_empty

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

acdcjunior
fonte
5

Isso funcionará nas inicializações Spring 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
}
Deva
fonte
1
Nesse mesmo @JsonInclude(JsonInclude.Include.NON_NULL)trabalhou para mim em Primavera arrancar 2.1.2 e Jackson anotações 2.9.0
manasouza
@manasouza Sim, eles mantiveram consistência em todas as atualizações.
Deva
3

Para o Jackson 2.5, use:

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

Isso está me incomodando há algum tempo e finalmente encontrei o problema. O problema ocorreu devido a uma importação incorreta. Antes eu estava usando

com.fasterxml.jackson.databind.annotation.JsonSerialize

O qual foi preterido. Basta substituir a importação por

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

e use-o como

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

Configuração global se você usar o 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;
    }

}
Xelian
fonte
Definir o serializationInclusion não adiciona um ao outro. public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; Deve-se usar o raio maior da enumeração de inclusão. por exemplo, NON_ABSENT inclui NON_NULL e NON_EMPTY inclui ambos. Por isso, só deve ser o builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); JacksonInclude doc #
Olgun Kaya
2

Se você estiver tentando serializar uma lista de objetos e um deles for nulo, você acabará incluindo o item nulo no JSON, mesmo com

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

vai resultar em:

[{myObject},null]

para conseguir esta:

[{myObject}]

pode-se fazer algo como:

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

DICA: Se você estiver usando o DropWizard, poderá recuperar o que ObjectMapperestá sendo usado por Jersey usandoenvironment.getObjectMapper()

user3474985
fonte
1

Temos muitas respostas para essa pergunta. Esta resposta pode ser útil em alguns cenários. Se você deseja ignorar os valores nulos, pode usar o NOT_NULL no nível da classe. como abaixo

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

Às vezes, você pode precisar ignorar os valores vazios, como você pode ter inicializado o arrayList, mas não há elementos nessa lista. Nesse período, usando a anotação NOT_EMPTY para ignorar esses campos de valores vazios

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

fonte
0

Jackson 2.x + use

mapper.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.NON_NULL);
mekdev
fonte
.withSerializationInclusion(JsonInclude.Include.NON_NULL)em vez disso, certo?
herau
Obrigado por apontar isso, vou adiar a atualização :-(
ZiglioUK 5/15
@ruslan: Provavelmente porque a documentação getSerializationConfig()diz: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

Além disso, você deve alterar sua abordagem ao usar o Map myVariable, conforme descrito na documentação para eliminar 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
atom88
fonte
0

Caso um

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

Caso dois

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

Se someStringfor nulo, será ignorado nos dois casos. Se someStringestiver "", apenas será ignorado no caso dois.

O mesmo para List = nullouList.size() = 0

Nguyen Minh Hien
fonte