Spring Boot JUnit集成测试无法发送请求体(objectMapper序列化问题)
Spring Boot JUnit集成测试请求体400 Bad Request问题解决
问题场景
在Spring Boot JUnit集成测试中,向POST接口发送带JSON请求体的请求时,收到400 Bad Request错误,预期返回200 Ok。具体情况:
- 实体类
AdminRefreshTokenRequest使用@NotBlank校验字段,配合Lombok的@Data和@Builder - 控制器方法通过
@RequestBody接收该实体类参数 - 测试用
MockMvc发送JSON格式请求,报错信息显示"Failed to read request" - 移除
@RequestBody后,控制器中参数值为null
核心原因
Jackson(Spring默认的JSON序列化工具)在反序列化JSON到Java对象时,需要类存在无参构造函数。而Lombok的@Builder注解默认不会生成无参构造,仅生成建造者模式的构造逻辑;@Data注解也不会自动生成无参构造(除非没有其他显式构造函数),这直接导致Jackson无法实例化AdminRefreshTokenRequest对象,触发请求体读取失败,返回400错误。
解决方案
1. 给实体类添加无参构造函数
通过Lombok注解或手动添加的方式,确保实体类存在无参构造:
import jakarta.validation.constraints.NotBlank; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; @Data @Builder @NoArgsConstructor // 显式生成无参构造 @AllArgsConstructor // 配合@Builder生成全参构造 public class AdminRefreshTokenRequest { @NotBlank private String refreshToken; }
或者手动添加无参构造:
@Data @Builder public class AdminRefreshTokenRequest { @NotBlank private String refreshToken; // 手动添加无参构造 public AdminRefreshTokenRequest() {} }
2. 启用请求参数校验并查看详细错误
在控制器方法的@RequestBody参数上添加@Valid注解,这样如果是字段校验失败(比如refreshToken为空),会返回具体的校验错误信息,方便排查:
@PostMapping("/refreshtoken") public ResponseEntity<?> refreshToken(@RequestBody @Valid AdminRefreshTokenRequest refreshTokenRequest) { // 业务逻辑 }
3. 验证测试中的ObjectMapper配置
确保测试中注入的ObjectMapper是Spring Boot自动配置的实例,避免自定义配置导致序列化/反序列化异常。如果有自定义的Jackson配置,需确认其兼容实体类的序列化逻辑。
验证
修改实体类添加无参构造后,重新运行集成测试,Jackson可以正常反序列化请求体,控制器能正确接收参数,接口将返回预期的200 Ok状态。
内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu
相关产品推荐
相关产品推荐

