使用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
相关产品推荐
相关产品推荐

