PAYATHON 2026

Jackson 2 升级到 Jackson 3 后,为什么 JSON 中缺少 events 字段?

数据小陈

结论

仅凭这些片段,还无法确定 events 消失的具体原因。先检查 MyData 是否有可识别的 public getEvents(),再查看属性是否被注解、过滤器或自定义序列化器排除,以及 HTTP 响应使用的 Jackson 配置。

如果私有字段缺少可识别的读取入口,可以添加标准 getter,或使用 @JsonProperty 显式声明属性。如果 getter 已存在且返回非空列表,就需要继续检查过滤规则,不能直接认定 Jackson 3 不再序列化集合。

先检查 events 的 getter

示例只展示了 MyData 的字段,省略部分中的访问方法没有展示。默认属性识别规则会识别 public getter,单独声明 private 字段不足以保证它出现在 JSON 中。Jackson 属性识别说明

可以在现有 MyData 中确认或补充:

public List<MyEvents> getEvents() {
    return events;
}

检查方法是否为 public、名称是否为 getEvents,以及它是否直接返回当前的 events。如果使用了代码生成工具,还要确认最终编译出的类确实包含这个方法。

普通响应序列化不需要仅为输出集合而添加 setter。字段中有一个元素,也不代表 getter 返回的是同一个非空集合;应检查即将返回的对象上 getter 的实际返回值。

需要直接暴露字段时,使用明确的属性注解

如果 DTO 采用字段映射,可以在现有字段上显式声明 JSON 属性:

import com.fasterxml.jackson.annotation.JsonProperty;

// 放在现有 MyData 类中
@JsonProperty("events")
private List<MyEvents> events = new ArrayList<MyEvents>();

Jackson 3 的 jackson-annotations 仍使用 com.fasterxml.jackson.annotation 包,无需将这个 import 改成 tools.jackson.annotation。Spring Boot 4.0 迁移说明

这个方法适用于属性未被识别的情况。如果存在忽略规则或自定义序列化逻辑,还需要检查相应配置;只加一个注解不能保证覆盖所有情况。

getter 正常时,检查排除规则和实际使用的 mapper

可以按以下顺序排查:

  1. 检查 events 字段、getter、父类和 mix-in 中是否有 @JsonIgnore、@JsonIgnoreProperties 或 @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)。
  2. 检查当前接口是否使用了 @JsonView、属性过滤器,或是否为 MyData 注册了自定义序列化器。
  3. 检查 @JsonInclude 和全局包含策略。如果 getter 返回的是包含一个元素的普通列表,单纯的 NON_EMPTY 策略通常不能解释整个字段消失。
  4. 检查迁移前后的可见性配置、模块和 mapper 定制是否仍然生效。

Spring Boot 4 默认使用 Jackson 3,并自动配置 JsonMapper。即使项目中仍有 Jackson 2 的 ObjectMapper,也不能据此判断 HTTP 响应使用了它。Spring Boot JSON 配置说明

可以使用 Spring 管理的 Jackson 3 JsonMapper 序列化同一个响应对象进行对比。下面的方法参数应传入应用中实际使用的 mapper 和响应实例:

import tools.jackson.databind.json.JsonMapper;

public String serializeForDiagnosis(JsonMapper mapper, MyResponse response) {
    return mapper.writeValueAsString(response);
}

如果直接序列化也缺少 events,就检查 DTO、注解和 mapper 配置;如果直接序列化包含该字段,而接口响应中没有,就检查 HTTP 消息转换器、接口视图、过滤逻辑,以及控制器最终返回的是否为同一个对象。

VIA_DTO 配置能否解释这个现象?

pageSerializationMode = VIA_DTO 用于将 PageImpl 转换为稳定的分页表示。示例中的 MyResponse.data 是 List<MyData>,现有配置不足以解释普通 DTO 的 events 属性为何被省略。配置类中的 @PostConstruct 也只是记录初始化日志。Spring Data 分页序列化说明

Jackson 3 确实调整了部分默认值,例如 USE_GETTERS_AS_SETTERS 默认关闭。该选项用于反序列化时通过 getter 获取集合并填充内容,不能直接解释响应序列化时字段缺失。Jackson MapperFeature 定义

示例中的两个细节

集合声明使用的是 MyEvents,展示的事件类则是 MyEvent。需要核对实际项目中的名称;上面的访问方法示例保留了集合声明中的 MyEvents。

JSON 示例中的 2026-03-30T29:85:42.000Z 不是有效时间,{ ... } 则是省略表示。排查时应使用真实响应和合法日期,避免这些细节干扰复现;它们本身不能证明 events 缺失的原因。

备注:内容仅供参考。