如果字段为空,如何告诉杰克逊在序列化期间忽略该字段?


687

如果该字段的值为null,如何配置Jackson在序列化期间忽略该字段的值。

例如:

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

Answers:


1102

要使用Jackson> 2.0抑制具有空值的序列化属性,可以直接配置ObjectMapper或使用@JsonInclude批注:

mapper.setSerializationInclusion(Include.NON_NULL);

要么:

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

或者,您可以@JsonInclude在getter中使用,以便在值不为null时显示属性。

如何防止Map内的空值和bean内的空字段无法通过Jackson序列化的回答提供了一个更完整的示例。


81
我的项目,这个工作:@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL); 不知何故您的注释不可用。
伊曼纽尔·图扎里

13
该API在2.0版本中有所变化。
程序员布鲁斯(Bruce)

10
@ProgrammerBruce -1会相应地更改答案,因为您知道更改。
Martin Asenov

19
是的,我只是确认了这种@JsonInclude表示法不起作用,但这就像一个魅力:(@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 我将杰克逊1.9.12和Spring 3.2.2结合使用)
gstroup 2013年

17
@MartinAsenov-答案显示了最新的API;它已从@JsonSerialize语法更改为@JsonInclude。不建议使用较旧的语法。
Logan Pickup

128

对于Jackson> 1.9.11和<2.x,请使用@JsonSerialize注释来做到这一点:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)


10
如今(Jackson 2.x)已弃用这种方法。
rustyx

39
@JsonInclude(JsonInclude.Include.NON_NULL)
ZiglioUK 2014年

3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)不起作用。可空值被序列化。
2014年

1
已过时,但是如果您需要维护旧的东西,那么这个答案是完全可以的!非常感谢@WTK :)
DominikAngerer


122

只是为了扩展其他答案-如果您需要基于每个字段控制空值的省略,请为有问题的字段添加注释(或为字段的“ getter”添加注释)。

例如-这里只fieldOne从JSON被ommitted如果它是空的。fieldTwo不论是否为null,都将始终包含在内。

public class Foo {

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

    private String fieldTwo;
}

要忽略该类中的所有空值作为默认值,请为该类添加注释。如有必要,仍可以使用按字段/获取器注释来覆盖此默认值。

示例-在此处fieldOnefieldTwo如果它们分别为null,则将从json省略,因为这是类注释的默认设置。fieldThree但是,由于字段上有注释,因此它将覆盖默认值并始终包含在内。

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

    private String fieldOne;

    private String fieldTwo;

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

更新

以上是针对Jackson 2的。对于早期版本的Jackson,您需要使用:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

代替

@JsonInclude(JsonInclude.Include.NON_NULL)

如果此更新有用,请在下面更新ZiglioUK的答案,它指出了较新的Jackson 2批注,而我要更新答案才能使用它!


字段上的注释不应该总是被覆盖吗?
Abhinav Vishak '18

@AbhinavVishak你说得对-谢谢!当我更新答案以使用Jackson 2时,这是一个复制粘贴的错字。编辑。
davnicwil

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 已弃用
Yar

1
@Yar是的,在Jackson 2.x中已弃用。我说,你需要使用仅在早期版本的杰克逊这里不仅是没有过时,它是唯一的选择。
davnicwil

60

在Jackson 2.x中,使用:

@JsonInclude(JsonInclude.Include.NON_NULL)

这是要放在现场吗?
2014年

1
@ams,此注释应包装一个类
Edgard

您还可以输入完全限定的名称吗?杰克逊有多个具有相同名称和不同包装的注释,因此模棱两可。
文斯(Vince)

您是说Jackson中有多个@JsonInclude注释吗?我不知道。那么完全合格的名称应该是什么?随时编辑答案
ZiglioUK

名称的混淆很可能是由于Jackson 1.x和2.x对所有内容使用了不同的Java包,以避免类加载器冲突(WRT不兼容的类版本)。由于此答案是针对2.x版本的,因此注释包应为com.fasterxml.jackson.annotation-杰克逊1.x版本org.codehaus.jackson.annoation
StaxMan

39

您可以使用以下映射器配置:

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

从2.5开始,您可以使用:

mapper.setSerializationInclusion(Include.NON_NULL);

3
由于自1.9起已弃用,请使用mapper.getSerializationConfig()。withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);。
2014年

7
..或直接:mapper.setSerializationInclusion(NON_NULL);
2014年

@ruslan:可能是因为的文档getSerializationConfig() 说: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

对于2.5.4使用mapper.setSerializationInclusion(Include.NON_NULL);
Arturo Volpe 2016年


12

就我而言

@JsonInclude(Include.NON_EMPTY)

使它工作。


2
NON_EMPTY与NON_NULL略有不同-它将忽略空值,这是正确的,但将忽略被认为为空的值,这可能不是您期望的行为。看到杰克逊的javadoc更多信息
davnicwil

我喜欢这个答案,因为从真正可选的东西中返回Optional是一个好主意,仅使用NON_NULL,您将得到类似{ }null的东西,这毫无意义地将Java习惯用语传递给使用者。与AtomicReference相同-消费者不在乎开发人员如何选择对响应的内部表示实施线程安全。
卢卡斯·罗斯

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

应该管用。

Include.NON_EMPTY指示如果属性的值不为null且不为空,则该属性被序列化。 Include.NON_NULL指示属性的值不为null时,将对其进行序列化。


2
JsonInclude.Include.NON_EMPTY-足够了,因为它涵盖了NOT_NULL情况
Ilya Buziuk



5

这将在Spring Boot 2.0.3+和Jackson 2.0+中运行

import com.fasterxml.jackson.annotation.JsonInclude;

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

1
@JsonInclude(JsonInclude.Include.NON_NULL)对于Spring Boot 2.1.2Jackson注释2.9.0
-manasouza

@manasouza是的,他们保持了所有更新的一致性。
德瓦(Deva)

3

对于Jackson 2.5使用:

@JsonInclude(content=Include.NON_NULL)

2

这一直困扰着我很长时间,我终于找到了问题。该问题是由于导入错误所致。之前我一直在使用

com.fasterxml.jackson.databind.annotation.JsonSerialize

已弃用。只需将导入替换为

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

并用作

@JsonSerialize(include=Inclusion.NON_NULL)

2

如果使用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;
    }

}

设置serializationInclusion不会彼此添加。public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; 应当使用更大的包含枚举半径。例如,NON_ABSENT包含NON_NULL,NON_EMPTY包含两者。因此,只应该是builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); JacksonInclude DOC
Olgun卡亚

2

如果您要序列化对象列表,并且其中一个为null,则最终会在JSON中包含null项目,即使

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

将导致:

[{myObject},null]

得到这个:

[{myObject}]

一个人可以做类似的事情:

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

提示:如果您使用的是DropWizard,则可以ObjectMapper使用environment.getObjectMapper()


1

我们对这个问题有很多答案。在某些情况下,此答案可能会有所帮助。如果您想忽略空值,则可以在类级别使用NOT_NULL。如下

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

有时您可能需要忽略空值,例如您可能已经初始化了arrayList但该列表中没有任何元素。

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

0

Jackson 2.x +使用

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

.withSerializationInclusion(JsonInclude.Include.NON_NULL)相反吧?
herau 2014年

感谢您指出这一点,我将阻止升级:-(
ZiglioUK

@ruslan:可能是因为的文档getSerializationConfig()说: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

此外,在使用Map myVariable时,还必须更改文档中所述的方法以消除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

案例一

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

案例二

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

如果someString为null,则在两种情况下都将被忽略。如果someString为“”,则仅在情况二中被忽略。

List = null或相同List.size() = 0

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.