导读:本期聚焦于周翰文创作的《如何解决 Spring Boot 接口返回 null 值字段不显示的问题?》,敬请观看详情。接口返回的JSON数据里,字段值为null时直接消失不见了,前端拿不到属性名就报undefined错误,这是Spring Boot项目中常见的坑。造成这个现象的根源在于Jackson默认配置会在序列化时忽略null值。本文详细讲解三种主流解决方案:全局配置application.yml开关、自定义ObjectMapper定制序列化策略、使用@JsonInclude注解按需控制单个类或字段。同时分析每种方式的适用场景和潜在副作用,比如全局开启后可能带来的响应体膨胀问题,以及如何根据业务需要选择保留null还是空字符串,帮助开发者彻底搞懂null值序列化的处理逻辑。

在Spring Boot项目开发中,后端同学经常遇到一个奇怪的现象:实体类里明明定义了某个字段,查询结果里该字段确实是null,但接口返回的JSON数据中压根找不到这个字段名。前端同学取值时自然就报了undefined的错误,双方来回扯皮半天才发现问题出在序列化配置上。这篇文章就来彻底讲清楚null值字段不显示的原因,以及几种实用的解决方案。

如何解决 Spring Boot 接口返回 null 值字段不显示的问题?

为什么null值字段会在返回结果中消失

Spring Boot默认使用Jackson作为JSON序列化框架,而Jackson在序列化Java对象时,对于值为null的字段,默认行为是直接忽略、不输出。也就是说,如果你的实体类有name、age、address三个字段,其中address为null,那么返回的JSON里只会出现name和age两个属性。

这个默认行为在某些场景下其实是合理的,比如数据量大、null字段多的接口,省略null可以减少响应体体积。但在前后端强约定的项目中,字段缺失会带来麻烦:前端需要额外判断属性是否存在,TypeScript项目中的类型定义也会对不上,甚至一些表格组件会因为属性缺失而显示异常。

还有一种常见情况是项目里有人自定义了配置,比如在application.yml中开启了non_null策略,或者通过@Configuration类定制了ObjectMapper,后来的开发者不了解背景,排查起来就很费劲。所以第一步是确认项目的序列化配置现状。

方案一:全局配置文件开启null值返回

最简单的办法是修改application.yml,直接告诉Jackson在序列化时包含null字段:

spring:
  jackson:
    default-property-inclusion: always

如果只是想忽略null,可以设置为non_null;其他可选值还有non_empty(忽略空字符串、空集合等)和non_absent(忽略Optional.empty等)。这里选择always表示任何情况都输出字段,null值会以JSON的null形式出现在响应中。

这种方式的好处是改动小、生效范围全局,一行配置解决所有接口的问题。但也要注意副作用:如果项目接口很多、实体类字段很长,全局开启后响应体会明显变大,对带宽敏感的移动端场景需要权衡。另外,配置的加载依赖于Spring Boot自动装配机制,如果你自己手动创建过ObjectMapper的Bean,这个yml配置可能会失效,这一点后面会讲到。

方案二:通过代码配置ObjectMapper

对于需要更精细控制的场景,可以写一个配置类,显式定制序列化行为:

@Configuration
public class JacksonConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> builder.serializationInclusion(JsonInclude.Include.ALWAYS);
    }
}

使用Jackson2ObjectMapperBuilderCustomizer的好处是不会替换掉Spring Boot默认创建的ObjectMapper,而是在其基础上做增强,兼容性最好。如果你选择直接定义一个ObjectMapper Bean来覆盖默认行为,代码会像这样:

@Configuration
public class JacksonConfig {

    @Primary
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        return mapper;
    }
}

需要注意,直接覆盖ObjectMapper会丢掉Spring Boot默认注册的一些模块(如JavaTimeModule对LocalDateTime的支持),除非你清楚自己在做什么,否则推荐用Customizer的方式。这种方式适合团队有统一序列化规范、需要集中管理的场景,配置集中在代码里也方便版本管理和review。

方案三:使用@JsonInclude注解按需控制

如果只有个别实体类需要输出null字段,不想影响全局,可以在类或字段级别使用注解:

@Data
@JsonInclude(JsonInclude.Include.ALWAYS)
public class UserVO {

    private String name;

    private Integer age;

    // 单独控制某个字段:null时不序列化
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String internalRemark;

类级别的注解作用于整个对象,字段级别的注解优先级更高,可以覆盖类级别的配置。这种方式的粒度最细,非常适合同一个项目里不同接口有不同返回要求的场景,比如对外接口尽量精简、内部管理后台则要求字段完整。

注解方式的缺点是侵入性强,每个需要的类都要加注解,字段多了容易遗漏。实践中常见的做法是定义一个基础VO类加上注解,其他VO继承它,减少重复代码。

方案对比与选择建议

三种方案没有绝对的好坏,关键看项目的实际需求。简单项目、想快速解决问题,用yml全局配置最省事;多模块项目或者需要统一技术规范的中大型项目,用配置类的代码方式更可控;字段级别差异化需求多,就混合使用注解。

另外还有一个容易踩的坑:如果项目中同时引入了Fastjson并配置为消息转换器,那么上述Jackson的配置全部无效,需要去改Fastjson的SerializerFeature配置,比如加上WriteMapNullValue让Map中的null值也能输出。排查问题时先确认当前生效的到底是哪个JSON框架,否则改了半天配置毫无效果。

最后提醒一点,接口返回null字段还是空字符串,最好在团队内部统一约定并写进接口文档,避免后端返回null、前端期望空串之类的隐性分歧。序列化配置看似是小问题,但处理不好会反复消耗前后端的沟通成本,值得在一开始就定好规矩。

Spring Bootnull值过滤Jackson配置修改时间:2026-09-15 16:24:31

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260915/57375.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。