jackson对于对象序列化的时候默认空值和手动传入的null的不同处理
Jackson 在序列化对象时如何处理默认的空值和手动传入的 null
,其实归结于它的序列化机制和注解配置。默认情况下,Jackson 不区分 手动设置的 null
和 对象中字段的默认空值,但可以通过配置来改变其行为。具体细节如下:
1. 默认行为:手动传入的 null
和默认空值
Jackson 在序列化时,对于对象的字段,遵循如下规则:
- 显式设置的
null
:当你手动为字段赋值为null
,Jackson 认为这是一个显式的null
值,会将其序列化为"field": null
。 - 默认
null
值:如果某个字段没有被显式赋值(比如对象初始化时未赋值),其值默认为null
,Jackson 可能会忽略这些null
值,除非你配置让它保留这些字段。
关键在于 Jackson 的 JsonInclude
行为:
java 复制代码 @JsonInclude(JsonInclude.Include.NON_NULL)
这是 Jackson 的默认配置,意思是忽略 null
值。因此,当字段为 null
且未显式赋值时,Jackson 会将其排除在最终的 JSON 之外。
2. 手动传入 null
的情况
当你在代码中手动将字段赋值为 null
时,Jackson 视作你明确地希望该字段的值为 null
,因此在序列化时会包含该字段,结果如下:
java 复制代码 class Example { public String field1; } Example obj = new Example(); obj.field1 = null; // 手动设置为null
Jackson 序列化输出为:
json 复制代码 { "field1": null }
这是因为 Jackson 认为你有意将 field1
赋值为 null
,它会反映在最终的 JSON 中。
3. 区分手动 null
和默认 null
的配置
虽然 Jackson 本质上不区分“手动设置 null
”与“默认 null
”,但你可以通过配置和注解来控制 Jackson 的序列化行为。以下是一些常见的配置:
a. 全局配置 null
序列化行为
通过 Spring Boot 的配置文件,或直接在代码中配置 Jackson 的 ObjectMapper
,你可以全局控制 Jackson 是否包含 null
字段:
properties 复制代码 # 在 application.properties 或 application.yml 中添加配置 spring.jackson.default-property-inclusion=always
或者在代码中设置:
java 复制代码 ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
这将让 Jackson 始终序列化 null
字段,无论它们是手动设置的还是默认的 null
值。
b. 局部控制:类或字段级别的 null
序列化
你还可以通过注解在某个类或字段上控制 null
的序列化行为。例如:
- 包含所有
null
字段:
java 复制代码 @JsonInclude(JsonInclude.Include.ALWAYS) public class MyClass { public String field1; public String field2; }
- 在这种情况下,
field1
和field2
即使为null
,Jackson 也会将它们序列化到 JSON 中。 - 忽略
null
字段: - 默认的 Jackson 序列化行为就是忽略
null
值。如果你希望某个类或字段不包含null
,可以使用以下配置:
java 复制代码 @JsonInclude(JsonInclude.Include.NON_NULL) public class MyClass { public String field1; public String field2; }
- 这样,当
field1
或field2
为null
时,Jackson 将不会将它们包含在 JSON 中。
4. Jackson 的工作机制
Jackson 并不会特别区分手动设置的 null
和未显式赋值的 null
。它通过以下方式来确定是否序列化:
- 字段是否显式赋值:只要某个字段被显式赋值为
null
,Jackson 会认为这是开发者的明确意图,因此会包含这个null
值。 - 字段默认值:如果字段默认是
null
且 Jackson 被配置为忽略null
值,默认情况下这些字段不会被序列化。
Jackson 通过 JsonInclude
注解或全局配置,决定是否在 JSON 中保留 null
字段。
总结
Jackson 在序列化时不严格区分手动传入的 null
和默认空值,它只关心字段的值是 null
还是非 null
。但是,通过 JsonInclude
注解或配置,你可以灵活控制是否要在 JSON 中保留 null
值,确保在你需要的时候将字段序列化出来。
在 Spring MVC 中,如果返回的对象中某些字段为 null
,默认情况下这些字段可能不会被序列化到 JSON 响应中,因此对方解析时看不到这些字段。这个行为主要由 Jackson(默认的 JSON 序列化框架)控制。
原因: Jackson 默认会忽略值为 null
的字段,以减少不必要的数据传输。这就是为什么当字段为 null
时,生成的 JSON 中不会包含这些字段。
解决方案:
- 全局配置:如果你希望即使字段值为
null
,也要在响应的 JSON 中显示,可以通过配置 Jackson 来改变这一行为。 在application.properties
或application.yml
中添加以下配置:
properties 复制代码 spring.jackson.default-property-inclusion=non_null
- 这将让 Jackson 在序列化时包含
null
值。 - 局部配置:你也可以通过注解的方式控制某个类或字段是否序列化
null
值。 在需要包含null
值的类或字段上使用@JsonInclude
注解:
java 复制代码 import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.ALWAYS) public class MyClass { private String field1; private String field2; // 可能为null }
- 这样,即使
field2
为null
,也会被包含在 JSON 响应中。 - 自定义序列化:你还可以自定义序列化逻辑,决定何时包含
null
值,甚至可以为null
值提供默认值。
通过这些方式,你可以灵活控制对象的 null
字段在 JSON 中的表现方式。