@Builder注释导致@RequestBody的前端json反序列化失败,HTTP400

项目里发生了一个bug,就是前端请求一个接口时候,报了HTTP 400 Bad Request

通常来说这个问题是前后端的参数没对齐,比如前端传了个String,但后端对应的是Integer。

所以我就排查了半天,结果没发现啥错误,有点懵。

最后发现问题出在Controller层里,@RequestBody SubmitParam。

而SubmitParam中的某一个参数,我给加上了@Data和@Builder,注释,这个@Builder注释可好,直接给我干400了,其实去掉@Builder或者加上@AllArgsConstructor和@NoArgsConstructor都可以解决这个问题。

这是为什么呢,因为@Builder算是Lombok里很常用的注释了,可以简化我们构建对象,避免大量set的语句。当你在一个类上使用@Builder注解时,Lombok会自动生成一个静态内部类Builder,将目标类的参数都复制到Builder类里,用于创建该类的实例,提供一种流畅的链式方式来构建对象。

举个例子

复制代码
import lombok.Builder;

@Builder
public class Person {
    private String name;
    private int age;
    private String address;
}

// 在其他地方的代码中
Person person = Person.builder()
                      .name("John")
                      .age(30)
                      .address("123 Main St")
                      .build();

坑就在@Builder注释在目标类中创建一个私有构造函数,参数为 Builder类型。在Builder类中提供设置各个参数的方法,并返回当前对象。最后在 Builder类中提供一个 build方法,用来创建目标类的实例,并将各个参数赋值给目标类。

然而!!!!@RequestBody在接受前端传来的json反序列化为Java对象时候,会默认调用无参构造的,@Builder会给默认的无参构造器顶掉,这就会导致@RequestBody没法替我们反序列化了,就会导致400 Bad Request。

另外需要注意:

(1)如果你在类上使用了 @Builder 注解,那么你需要手动添加一个无参构造函数,否则有些序列化框架需要通过 newInstance 构造对象时会报错。

(2)如果你在类上使用了 @Builder 注解,那么你不能再在构造函数或方法上使用 @Builder 注解,否则会导致重复生成构造器类。

(3)如果你想给某个属性设置一个默认值,那么你需要在属性上使用 @Builder.Default 注解,否则默认值会被忽略。

(4)如果你想让子类继承父类的属性,那么你需要在子类的全参构造函数上使用 @Builder 注解,并且在父类上使用 @AllArgsConstructor 注解,否则子类的构造器类不会包含父类的属性。

相关推荐
阿巴斯甜15 小时前
Predicate的使用:
java
阿巴斯甜15 小时前
Supplier的使用:
java
阿巴斯甜15 小时前
Function 用法:
java
做个文艺程序员16 小时前
流式输出(SSE)在 Spring Boot 中的实现【OpenClAW + Spring Boot 系列 第3篇】
java·spring boot·后端
逻辑驱动的ken16 小时前
Java高频面试考点场景题09
java·开发语言·数据库·算法·oracle·哈希算法·散列表
小手cool16 小时前
如何在Java中根据另一个配对集合对一个集合进行排序
java·开发语言
云烟成雨TD16 小时前
Spring AI Alibaba 1.x 系列【28】Nacos Skill 管理中心功能说明
java·人工智能·spring
升鲜宝供应链及收银系统源代码服务16 小时前
OMS 订单模块重构正式文档(一)---升鲜宝生鲜配送供应链管理系统
java·开发语言·重构·生鲜配送源代码·生鲜供应链源代码
Han.miracle16 小时前
Redis 全套笔记:基础 API + 三大架构 + 缓存三大问题
java·windows·redis
zzb158016 小时前
Fragment 生命周期深度图解:从 onAttach 到 onDetach 完整流程(面试必备)
android·java·面试·安卓