记一次因lombok升级引起的反序列化失败的bug

记一次因lombok升级引起的反序列化失败的bug

问题出现:

更新项目后,发现原来正常的接口报错,调试发现了报错信息为 json反序列化异常

no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)

字符串转换对象Area 失败,该对象上添加了lombok @Builder @Data 注解,使用的转换方式是 areaProvinceVOS = ObjectMapperFactory.getObjectMapper().readValue(json, valueTypeRef);

问题解决

通过报错信息发现类上缺少构造函数,于是在Area及其包含的子类上添加注解 @AllArgsConstructor @NoArgsConstructor ,序列化正常

原因解析

更新项目过程中,该接口内的代码没有更改过,但是更新了lombok版本,从1.16.22更新到了1.18.8。猜测是1.18 的@Builder 注解没有无参构造函数,导致反序列化失败

由于lombok是编译期起效的,于是查看一下编译后的字节码文件,果然是没有无参构造函数的。有一个全参构造器,但是对于jackson的类型转换是不适用的

在这里插入图片描述

### 使用 Lombok 进行序列化操作 为了简化 Java 类的编写并减少样板代码,Lombok 提供了一些有用的注解来处理对象的序列化反序列化。以下是具体方法: #### 1. 序列化的基础设置 当使用 Jackson 或其他 JSON 处理库时,可以通过 `@Data` 注解自动生成 getter 和 setter 方法以及 `toString()`、`equals()` 和 `hashCode()` 方法。 ```java import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class User { private final String name; private final int age; @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public User(@JsonProperty("name") String name, @JsonProperty("age") int age) { this.name = name; this.age = age; } } ``` 此段代码展示了如何通过 Lombok 的 `@Data` 自动生成必要的访问器方法,并利用 Jackson 的 `@JsonCreator` 来指定构造函数用于反序列化过程[^1]。 #### 2. 自定义字段排除或包含策略 有时可能希望某些字段不参与序列化/反序列化流程,这时可以借助于 `transient` 关键字或者 Jackson 特定的注解如 `@JsonIgnore`。 ```java import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @Getter @Setter @AllArgsConstructor public class Employee { private String firstName; @JsonIgnore private transient String password; // 不会被序列化 private String lastName; } ``` 这段例子说明了怎样标不需要被序列化的属性,既可以用标准的 `transient` 关键词也可以采用更灵活的方式——Jackson 的 `@JsonIgnore` 注解[^4]。 #### 3. 解决循环引用问题 如果存在双向关联的对象结构,在默认情况下可能会导致无限递归错误。此时可应用 `@JsonManagedReference` 和 `@JsonBackReference` 组合解决这一难题;另外一种方案则是使用 `@JsonIdentityInfo` 实现基于 ID 的引用跟踪机制。 ```java import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonManagedReference; import lombok.*; @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(staticName = "of") @Getter public static class Department { private Long id; private String departmentName; @JsonManagedReference List<Employee> employees; } @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(staticName = "of") @Getter public static class Employee { private Long id; private String employeeName; @JsonBackReference private Department department; } ``` 上述片段解释了如何运用这两个互补性的 Jackson 注解防止因循环依赖而引发的问题,同时也体现了 Lombok 对无参构造器的支持[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值