Spring Boot Reactive添加@Valid注解后控制器测试失败求助
问题分析与解决建议
核心问题定位
你遇到的Bad Request是因为实体类中complete字段的校验注解误用:
- 字段类型是基本类型
boolean,默认值为false,但你添加了@AssertTrue注解,该注解要求字段值必须为true,而测试代码中设置的是setComplete(false),直接触发校验失败。 - 另外,基本类型
boolean无法为null,所以@NotNull注解对它完全无效,属于冗余配置。
具体修复步骤
1. 修正实体类的校验逻辑
将complete字段改为Boolean包装类型,同时移除错误的@AssertTrue注解,保留@NotNull确保必须传入有效值(true/false):
@Data @Container(containerName = "myContainer") public class ToDo { @Id @PartitionKey @GeneratedValue private String id; @NotBlank(message = "Category must not be blank") private String category; @NotNull(message = "Complete must not be null") private Boolean complete; // 改为包装类型,支持null判断 @NotBlank(message = "Name must not be blank") private String name; }
2. 补充校验异常的处理逻辑
当前控制器只捕获了DuplicateItemException,但校验失败会抛出WebExchangeBindException,需要添加对应的错误处理,方便调试和返回友好提示:
@PostMapping public Mono<ResponseEntity<Object>> createTodo(@Valid @RequestBody ToDo toDoItem) { return toDoService.saveItem(toDoItem) .map(savedItem -> ResponseEntity.status(HttpStatus.CREATED).body(savedItem)) .onErrorResume(DuplicateItemException.class, ex -> Mono.just(ResponseEntity.status(HttpStatus.BAD_REQUEST).body("重复的待办项"))) .onErrorResume(WebExchangeBindException.class, ex -> { // 提取具体的校验错误信息 List<String> errorMessages = ex.getBindingResult().getFieldErrors() .stream() .map(FieldError::getDefaultMessage) .collect(Collectors.toList()); return Mono.just(ResponseEntity.badRequest().body(errorMessages)); }); }
3. 确认DTO与实体的转换正确性
测试代码中使用的是ToDoDAO,而控制器接收的是ToDo实体,需确保两者的字段映射完全一致(比如complete字段的类型转换没有问题),避免因DTO转实体时出现字段值丢失或类型不匹配的情况。
测试验证
修改完成后,重新运行测试用例,setComplete(false)的请求会通过校验,接口将返回201 Created状态码。
内容的提问来源于stack exchange,提问作者Fabricio
相关产品推荐
相关产品推荐

