You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java Record实现复杂/嵌套对象的JSON序列化与反序列化

问题背景

给定如下JSON:

{
  "loginData": {
    "username": "foobar",
    "password": "secret"
  },
  "personalData": {
    "givenName": "Foo",
    "familyName": "Bar"
  }
}

以下是用于Jackson序列化与反序列化的POJO(包含部分可能冗余的Lombok注解):

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private LoginData loginData;
    private PersonalData personalData;

    @Builder
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    public static class LoginData {
        private String username;
        private String password;
    }

    @Builder
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    public static class PersonalData {
        private String givenName;
        private String familyName;
    }
}

我了解简单的Record定义如下:

public record LoginData(String username, String password) {}

想了解是否可以使用Java中相对较新的Record概念复现该结构,以及Record是否可用于需通过Jackson转换为JSON的嵌套/复杂对象?


答案

完全可以用Java Record复现这个嵌套结构,且Jackson 2.12及以上版本对Record有原生支持,能直接处理嵌套Record的序列化与反序列化。

1. 嵌套Record的实现方式

你可以用嵌套Record替代原有的嵌套静态类,代码会简洁很多:

public record User(LoginData loginData, PersonalData personalData) {}

public record LoginData(String username, String password) {}

public record PersonalData(String givenName, String familyName) {}

如果想把内部Record定义在User类中作为嵌套类型,也可以这样写:

public record User(User.LoginData loginData, User.PersonalData personalData) {
    public record LoginData(String username, String password) {}
    public record PersonalData(String givenName, String familyName) {}
}

2. Jackson处理Record的关键要点

  • 版本要求:必须使用Jackson 2.12或更高版本,该版本开始原生支持Java 16引入的Record类型。
  • 自动映射规则:Jackson会自动识别Record的组件(即定义时的参数),直接映射为JSON的键值对,无需额外添加@JsonProperty注解(除非需要自定义字段名)。
  • 构造器适配:Record没有无参构造器,但Jackson会直接调用Record的全参构造器实例化对象,不会影响反序列化。
  • 自定义字段名:如果需要让Record组件名与JSON字段名不一致,可通过@JsonProperty注解调整:
    public record LoginData(@JsonProperty("user_name") String username, String password) {}
    

3. 与原Lombok POJO的对比

  • 代码更简洁:无需编写Lombok的各类注解,Record自动生成equals()、hashCode()、toString()方法,以及不带get前缀的组件访问器(比如username()),Jackson会自动适配这类访问器。
  • 天然不可变:Record实例创建后无法修改字段值,作为数据传输对象(DTO)时更安全。

内容的提问来源于stack exchange,提问作者Robert Strauch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:25:32