Spring中@Valid校验失效:非法请求未触发预期校验异常
问题排查与解决
1. 基本类型无法接收null,导致amount字段校验失效
你的TransferRequestDTO中amount是long基本数据类型,当请求传入null时,Spring会自动将其转换为默认值0,而@Min(0)允许0值,所以这个字段不会触发校验。
解决办法:将amount改为Long包装类型,并添加@NotNull注解确保非空:
@Getter @Setter @AllArgsConstructor @Builder public class TransferRequestDTO { @NotBlank private String originAccountNumber; @NotBlank private String destinationAccountNumber; @NotNull @Min(value = 1) // 若允许0则保留@Min(0),但必须搭配@NotNull private Long amount; }
2. 接口方法未标注@Valid,导致参数校验不触发
因为AccountController实现了AccountAPI接口,Spring的方法参数校验依赖AOP代理,而代理基于接口实现。如果接口中的方法参数没有标注@Valid,即使实现类加了@Valid,校验逻辑也不会被触发。
解决办法:在AccountAPI接口的对应方法参数上添加@Valid注解,示例:
public interface AccountAPI { // ...其他方法 void testPath(@Valid @RequestBody TransferRequestDTO transaction); }
3. 额外确认:校验依赖配置正常
你已添加spring-boot-starter-validation依赖,对于Spring Boot 2.3+版本,该依赖确实需要手动引入,你的配置是正确的。
验证测试
修改后重新发送测试请求:
{ "originAccountNumber":"", "destinationAccountNumber":"", "amount":null }
此时会触发MethodArgumentNotValidException,若需要自定义错误响应,可添加全局异常处理器:
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach(error -> { String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } }
内容的提问来源于stack exchange,提问作者Mateo Rada
相关产品推荐
相关产品推荐

