Jackson中@JsonInclude(Include.NON_NULL)的工作原理问询
Jackson中JsonInclude.NonNull排除null字段的实现机制
当JsonInclude设置为NonNull时,序列化过程中会自动跳过值为null的字段,核心逻辑围绕规则优先级判断和序列化前的空值校验展开:
- 配置优先级:局部注解
@JsonInclude(JsonInclude.Include.NON_NULL)(标注在类、字段或getter方法上)会覆盖全局配置(通过ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)设置的规则)。如果类上标注了该注解,所有字段默认遵循此规则;单个字段或方法的注解则仅对自身生效。 - 序列化前的空值校验:Jackson的核心序列化组件
BeanSerializer在处理每个字段时,会通过对应的BeanPropertyWriter(负责单个属性的序列化逻辑)执行空值判断。当规则为NON_NULL时,BeanPropertyWriter会调用isNullValue(Object value)方法检查字段值,若返回true(即值为null),则直接跳过该字段的序列化流程,不会将字段名和null值写入JSON生成器。 - 底层输出逻辑:JSON生成器
JsonGenerator只会接收通过校验的键值对,因此最终输出的JSON字符串中不会出现值为null的字段。
ObjectMapper处理@JsonInclude注解的完整流程
ObjectMapper.writeValueAsString()能识别并排除null字段,本质是完成了注解扫描-规则配置-序列化执行的完整链路:
- 注解扫描与元数据收集:
ObjectMapper初始化或首次处理目标类时,会通过JacksonAnnotationIntrospector(默认的注解解析器)扫描类、字段、getter方法上的@JsonInclude注解。扫描到的规则会被存入BeanDescription(类的元数据描述对象)和BeanPropertyDefinition(单个属性的元数据对象)中,同时会合并全局配置和局部注解的规则,确定每个属性最终遵循的Include策略。 - 序列化器的构建:
当需要序列化目标类时,ObjectMapper会为该类创建BeanSerializer实例。创建过程中,会根据收集到的Include规则为每个BeanPropertyWriter配置空值过滤逻辑——如果属性有局部注解规则就用局部的,没有则继承类或全局的规则。 - 序列化执行:
调用writeValueAsString()时,ObjectMapper会创建JsonGenerator,然后将对象序列化的工作委托给BeanSerializer。BeanSerializer遍历所有配置好的BeanPropertyWriter,每个writer先检查当前属性值是否符合预设的Include规则:若不符合(比如值为null且规则是NON_NULL)则跳过写入;符合则调用JsonGenerator的方法写入字段名和对应值,最终生成过滤后的JSON字符串。
补充说明:Jackson默认基于getter方法进行序列化,因此getter返回null的属性也会被NON_NULL规则排除;如果需要基于字段序列化,可通过ObjectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)调整配置。
内容的提问来源于stack exchange,提问作者SeopLee
相关产品推荐
相关产品推荐

