在使用 Jackson 的 `ObjectMapper` 进行对象序列化时,如何忽略值为 `null` 的字段是一个常见需求。默认情况下,Jackson 会将 `null` 字段包含在生成的 JSON 中,这可能导致传输数据冗余或前端解析异常。开发者常问:如何配置 `ObjectMapper` 使其自动跳过 `null` 值字段?常用方法是通过设置序列化特性:`objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)`。但部分开发者在实际应用中发现配置未生效,可能是因为注解与全局配置冲突、对象嵌套层级处理不当,或在 Spring MVC 中未正确集成 ObjectMapper 配置。如何确保该设置在整个应用中统一生效?
2条回答 默认 最新
薄荷白开水 2025-10-20 20:47关注1. Jackson 序列化中忽略 null 字段的基础配置
在使用
ObjectMapper进行对象序列化时,默认行为会将字段值为null的属性也输出到 JSON 中。例如:public class User { private String name; private Integer age; private String email; // 构造函数、getter、setter 省略 } // 序列化结果可能为:{"name":"John", "age":null, "email":null}为避免冗余,可通过设置全局包含策略来跳过 null 值:
ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);该配置确保只有非 null 的字段被写入 JSON 输出。
2. 配置未生效的常见原因分析
尽管设置了
setSerializationInclusion,但部分开发者反馈配置无效。主要原因包括:- @JsonInclude 注解覆盖全局设置:类或字段上显式标注了
@JsonInclude(JsonInclude.Include.ALWAYS),会优先于全局配置。 - 嵌套对象未继承配置:若子对象未共享同一
ObjectMapper实例,其序列化仍可能保留 null 字段。 - Spring MVC 默认 ObjectMapper 未替换:在 Web 应用中,Spring 使用自己的
HttpMessageConverter,若未正确注册自定义ObjectMapper,则配置不生效。 - Builder 模式或 Lombok 的影响:使用
@Data或@Builder时,生成的构造逻辑可能绕过预期序列化路径。
3. 全局配置与注解的优先级机制
Jackson 对序列化包含策略的处理遵循以下优先级顺序(从高到低):
优先级 配置来源 说明 1 字段级 @JsonInclude 直接作用于字段,最高优先级 2 类级 @JsonInclude 应用于整个类的所有字段 3 ObjectMapper.setSerializationInclusion() 全局默认策略,最低优先级 因此,若某个字段标注了
@JsonInclude(Include.ALWAYS),即使全局设为NON_NULL,该字段仍会被序列化。4. 在 Spring Boot 中统一注册 ObjectMapper
为了确保配置在整个应用中生效,需通过
WebMvcConfigurer替换默认的 JSON 转换器:@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper); converters.add(converter); } }或者使用
@Primary @Bean方式让 Spring 自动装配:@Bean @Primary public ObjectMapper objectMapper() { return new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); }5. 嵌套对象与集合类型的处理策略
对于嵌套结构,如 List 或 Map 中的元素为 null,
NON_NULL不会自动过滤集合中的 null 元素。需额外配置:objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); // 可进一步排除空集合、空字符串等此外,可结合以下设置增强控制力:
JsonInclude.Include.NON_ABSENT:适用于 Optional 类型JsonInclude.Include.CUSTOM:支持自定义判断逻辑
6. 验证配置是否生效的调试方法
可通过以下流程图判断配置执行路径:
graph TD A[开始序列化对象] --> B{是否存在@JsonInclude注解?} B -- 是 --> C[使用注解指定策略] B -- 否 --> D{类或字段是否有特殊配置?} D -- 是 --> E[按特定规则处理] D -- 否 --> F[使用ObjectMapper全局设置] F --> G[输出JSON结果]同时建议编写单元测试验证实际输出:
@Test public void should_skip_null_fields() throws JsonProcessingException { User user = new User("John", null, null); String json = mapper.writeValueAsString(user); assertThat(json).doesNotContain("age"); assertThat(json).doesNotContain("email"); }本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- @JsonInclude 注解覆盖全局设置:类或字段上显式标注了