商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何解决 Jackson 无法识别父类字段的问题

如何解决 Jackson 无法识别父类字段的问题

  发布于2026-07-14 阅读(0)

扫一扫,手机访问

当使用 Lombok 的 @Jacksonized 注解时,Jackson 在反序列化子类时可能忽略继承自父类的字段(如 recipient),导致 UnrecognizedPropertyException;根本原因在于 @Jacksonized 会强制 Jackson 使用 Lombok 生成的 Builder 进行反序列化,而该 Builder 默认仅识别子类显式声明的字段,不包含父类字段。

在涉及继承的 JSON 处理场景里,@Jacksonized 注解其实是一把典型的双刃剑。它确实能帮我们快速把 Builder 模式和 Jackson 集成起来,少写不少样板代码。但问题在于,它的默认行为根本没考虑继承链上父类字段的自动识别。举个例子,假设 Child 类继承了一个叫 Parent 的父类,而 Parent 里定义了这么一行:@JsonProperty("recipient") protected Recipient recipient;。按理说这是再正常不过的字段声明了,可一旦你用 @Jacksonized 去反序列化 JSON 字符串,Jackson 就会毫不留情地报错:

Unrecognized field "recipient" (class a.b.Child$ChildRequestBuilder), not marked as ignorable (1 known properties: "use_case")

看到了吧?Jackson 正试图把 "recipient" 这个字段塞进 Child 类的内部 Builder——也就是那个 Child$ChildRequestBuilder。而这个 Builder 是由 @Jacksonized 自动生成的,它压根儿就没声明对父类字段的支持。这才是问题的根源所在。

✅ 正确解决方案:移除或谨慎使用 @Jacksonized

说起来,最直接有效的方案其实很简单,就是把 @Jacksonized 注解删掉——尤其是在存在继承关系的类层级里。

看下面的代码,Parent 类保持其他注解不变,但去掉 @Jacksonized:

// Parent 类保持其他注解,但去掉 @Jacksonized@Builder//@Jacksonized ← 把这行删掉@EqualsAndHashCode@ToString@Getter@Setter@JsonInclude(JsonInclude.Include.NON_NULL)@AllArgsConstructor@NoArgsConstructor@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)@JsonSubTypes({    @JsonSubTypes.Type(value = Child.class, name = "Child")})public class Parent implements Serializable {    private static final long serialVersionUID = 6223930820946596247L;    @JsonProperty("recipient")    protected Recipient recipient;    // ...}

Child 类同理,也删掉 @Jacksonized:

// Child 类同理移除 @Jacksonized@Builder(builderMethodName = "childRequestBuilder")//@Jacksonized ← 删掉@EqualsAndHashCode@ToString@Getter@Setter@AllArgsConstructor@NoArgsConstructor@JsonInclude(JsonInclude.Include.NON_NULL)public class Child extends Parent implements Serializable {    private static final long serialVersionUID = -2848064640409441165L;    @JsonProperty("use_case")    private String useCase;}

移除了 @Jacksonized 之后,Jackson 就会回到它自己的标准反射机制上去了。配合上 @Getter 和 @Setter,它就能正确识别并绑定 recipient 这类继承来的字段。这时候再跑测试,通过是没问题的。

⚠️ 替代方案:如果实在离不开 @Jacksonized

当然,有些项目确实对 @Jacksonized 有比较强的依赖,比如需要定制 Builder 的构造逻辑。这种情况下也不是没有别的路可走,可以通过显式配置 Builder 字段映射来支持父类属性:

@Builder@Jacksonized// ... 其他注解public class Parent { ... }@Builder@Jacksonized@SuperBuilder // 替换成 @SuperBuilder(需要 Lombok 1.18.20+),这样就能支持继承字段了public class Child extends Parent { ... }

这里需要留个心:@SuperBuilder 确实是更安全的继承友好型替代方案,前提是 Lombok 版本必须 ≥ 1.18.20。而且它还需要配合 @Jacksonized 的 builder() 参数来指定 Builder 类型——具体的用法可以去查一下最新文档。不过说实话,对于绝大多数的项目来说,还是优先推荐去掉 @Jacksonized,老老实实依赖标准 Jackson 加上 Lombok 的 @Getter/@Setter 组合。这套方案简洁、稳定,而且没有歧义,不容易出幺蛾子。

? 验证建议

  • 在运行反序列化测试之前,最好先把生成的 JSON 字符串打印出来看一看,确认一下结构是不是符合预期;
  • 可以把 Jackson 的调试日志打开(比如 logging.level.com.fasterxml.jackson=DEBUG),观察字段绑定路径,这样排查问题会更直观;
  • 如果项目里确实需要 Builder 支持,也可以考虑手动写一个静态的 from() 方法,或者用 @JsonCreator 来做显式构造——这样能避免隐式 Builder 的意外干预。

总而言之,在涉及类继承的 Jackson 场景里,对 @Jacksonized 的“过度自动化”行为一定要保持警惕。明确控制序列化契约,远比依赖注解黑盒来得更可靠。

本文转载于:https://www.php.cn/faq/2815443.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注