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

Posted

技术标签:

【中文标题】如果值为空,如何告诉杰克逊在序列化期间忽略一个字段?【英文标题】:How to tell Jackson to ignore a field during serialization if its value is null? 【发布时间】:2012-07-30 05:53:12 【问题描述】:

如果该字段的值为空,如何将 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; 

【问题讨论】:

【参考方案1】:

要使用 Jackson >2.0 禁止序列化具有空值的属性,您可以 configure the ObjectMapper directly,或使用 @JsonInclude 注释:

mapper.setSerializationInclusion(Include.NON_NULL);

或:

@JsonInclude(Include.NON_NULL)
class Foo

  String bar;

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

my answer 到 How to prevent null values inside a Map and null fields inside a bean from getting serialized through Jackson 中提供了更完整的示例。

【讨论】:

对于我的项目,这有效:@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL);不知何故,您的注释不可用。 API 在 2.0 版本中有所改变。 @ProgrammerBruce -1 相应地更改您的答案,因为您知道更改。 是的,我刚刚确认 @JsonInclude 表示法不起作用,但这就像一个魅力:@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)(我正在使用 Jackson 1.9.12 和 Spring 3.2.2。) @MartinAsenov - 答案显示了最新的 API;它已从 @JsonSerialize 语法更改为 @JsonInclude。不推荐使用旧语法。【参考方案2】:

只是为了扩展其他答案 - 如果您需要在每个字段的基础上控制空值的省略,请注释相关字段(或者注释字段的“getter”)。

示例 - 这里只有 fieldOne 如果为空,则从 JSON 中省略。 fieldTwo 将始终包含在 JSON 中,无论它是否为 null。

public class Foo 

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

    private String fieldTwo;

要默认忽略类中的所有空值,请对类进行注释。如有必要,仍然可以使用每个字段/getter 注释来覆盖此默认值。

示例 - 这里的 fieldOnefieldTwo 如果它们分别为空,则将分别从 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 注释!

【讨论】:

字段上的注释不应该总是被覆盖吗? @AbhinavVishak 你是对的 - 谢谢!当我更新使用 Jackson 2 的答案时,这是一个复制粘贴错字。已编辑。 @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 已弃用 @Yar 是的,这在 Jackson 2.x 中已被弃用。我已经说过,您只需要在 Jackson 的早期版本中使用它,它不仅被弃用,而且是唯一的选择。【参考方案3】:

对于 Jackson > 1.9.11 和 @JsonSerialize 注释来做到这一点:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

【讨论】:

现在(Jackson 2.x)已弃用这种方法。 @JsonInclude(JsonInclude.Include.NON_NULL) @JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL) 不起作用。可空值被序列化。 它已被弃用,但如果您需要维护旧的东西,这个答案完全没问题!所以谢谢@WTK :) 附带说明,Jackson 1.9.12 是 WebSphere 8.5 中的标准版本,希望这些信息可以为其他人节省很多时间,我花了很多时间来解决这个问题 :-)【参考方案4】:

在 Jackson 2.x 中,使用:

@JsonInclude(JsonInclude.Include.NON_NULL)

【讨论】:

这个要放在场上吗? @ams ,这个注解应该包装一个类 您还可以包括完全限定名称吗? Jackson 有多个具有相同名称和不同包的注解,因此是模棱两可的。 你是说Jackson中有多个@JsonInclude注解吗?我不知道。那么完全限定名称应该是什么?随意编辑答案 名称混淆很可能是由于 Jackson 1.x 和 2.x 对所有内容使用不同的 Java 包,以避免类加载器冲突(wrt 不兼容的类版本)。由于此答案适用于 2.x,因此注释包将是 com.fasterxml.jackson.annotation -- Jackson 1.x 有 org.codehaus.jackson.annoation【参考方案5】:

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

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

从 2.5 开始,您可以使用:

mapper.setSerializationInclusion(Include.NON_NULL);

【讨论】:

由于在 1.9 中已弃用,请使用 mapper.getSerializationConfig().withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); ..或直接:mapper.setSerializationInclusion(NON_NULL); @ruslan:可能是因为getSerializationConfig() says的文档: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. 对于 2.5.4 使用 mapper.setSerializationInclusion(Include.NON_NULL);【参考方案6】:

你可以设置application.properties:

spring.jackson.default-property-inclusion=non_null

application.yaml:

spring:
  jackson:
    default-property-inclusion: non_null

http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

【讨论】:

【参考方案7】:

就我而言

@JsonInclude(Include.NON_EMPTY)

成功了。

【讨论】:

NON_EMPTY 与 NON_NULL 略有不同 - 它会忽略空值,这是真的,但会忽略被认为是空的值,这可能不是所需的行为。有关更多信息,请参阅 Jackson javadocs 我喜欢这个答案,因为从真正可选的事物中返回 Optional 是个好主意,并且仅使用 NON_NULL 你会得到类似 的 null 值,这会毫无意义地将 Java 习语传递给消费者.与 AtomicReference 相同——消费者不关心开发人员如何选择在响应的内部表示上强制执行线程安全。【参考方案8】:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)

应该可以。

Include.NON_EMPTY 表示如果属性的值不为 null 且不为空,则该属性被序列化。 Include.NON_NULL 表示如果属性的值不为空,则该属性被序列化。

【讨论】:

JsonInclude.Include.NON_EMPTY - 足够了,因为它涵盖了 NOT_NULL 情况【参考方案9】:

这将适用于 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

【讨论】:

同样的 @JsonInclude(JsonInclude.Include.NON_NULL)Spring boot 2.1.2Jackson annotations 2.9.0 上为我工作 @manasouza 是的,他们保持所有更新的一致性。【参考方案10】:

如果您想将此规则添加到 Jackson 2.6+ 中的所有模型,请使用:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

【讨论】:

【参考方案11】:

如果在Spring Boot中,可以直接通过属性文件自定义jacksonObjectMapper

例如application.yml:

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

可能的值是:

always|non_null|non_absent|non_default|non_empty

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

【讨论】:

【参考方案12】:

对于 Jackson 2.5 使用:

@JsonInclude(content=Include.NON_NULL)

【讨论】:

【参考方案13】:

如果您尝试序列化一个对象列表并且其中一个为 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,您可以使用 environment.getObjectMapper() 检索 Jersey 使用的 ObjectMapper

【讨论】:

【参考方案14】:

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

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)

【讨论】:

【参考方案15】:

如果你使用 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【参考方案16】:

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

@JsonInclude(Include.NON_NULL)
class Foo

  String bar;

有时您可能需要忽略空值,例如您可能已经初始化了 arrayList 但该列表中没有元素。那时使用 NOT_EMPTY 注释来忽略那些空值字段

@JsonInclude(Include.NON_EMPTY)
class Foo

  String bar;

【讨论】:

【参考方案17】:

案例一

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

案例二

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

如果someString 为空,则在这两种情况下都将被忽略。 如果someString 是“”,它只会在案例二中被忽略。

List = nullList.size() = 0 相同

【讨论】:

【参考方案18】:

Jackson 2.x+ 使用

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

【讨论】:

.withSerializationInclusion(JsonInclude.Include.NON_NULL) 不是吗? 感谢您指出这一点,我将推迟升级 :-( @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.【参考方案19】:

此外,在使用 Map myVariable 时,您必须更改方法,如文档中所述以消除空值:

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

【讨论】:

【参考方案20】:

试试这个 -

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public class XYZ 
    
    protected String field1;
    
    protected String field2;
 

对于非空值(在 getters/class 级别)-

@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)

【讨论】:

以上是关于如果值为空,如何告诉杰克逊在序列化期间忽略一个字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有jackson注释的情况下忽略反序列化的某些字段?

杰克逊在测试期间的 Access.WRITE_ONLY 空

杰克逊:我怎么能忽略getter但解析setter? [复制]

我如何告诉杰克逊忽略我无法控制源代码的属性?

Jackson忽略空字段

如何动态忽略杰克逊序列化的属性