在日常開發中,參數校驗是保障接口健壯性與數據安全的第一道防線。Spring Boot 為我們提供了基于 JSR-303/JSR-380 的強大校驗機制,通過注解與 AOP 實現了靈活且高效的數據校驗方式。本篇博客將詳細介紹 Spring Boot 中 @Valid
、@Validated
注解的使用方法,并深入解析其背后的原理與擴展能力。
一、引入依賴
Spring Boot 項目中默認支持 javax.validation
,但建議顯式引入:
<!-- Hibernate Validator 是實現規范最廣的一個實現 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
二、基礎注解使用
在 Java Bean 上添加注解,示例:
public class UserDTO {@NotBlank(message = "用戶名不能為空")private String username;@Email(message = "郵箱格式不正確")private String email;@Min(value = 18, message = "年齡必須 >= 18")@Max(value = 100, message = "年齡必須 <= 100")private Integer age;// Getter / Setter
}
三、在 Controller 中啟用校驗
1. 使用 @Valid
(javax.validation)注解:
@RestController
@RequestMapping("/user")
public class UserController {@PostMapping("/create")public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO user) {return ResponseEntity.ok("創建成功");}
}
2. 使用 @Validated
(Spring 提供)支持 分組校驗:
public class UserDTO {@NotBlank(message = "用戶名不能為空", groups = Create.class)private String username;public interface Create {}
}
@PostMapping("/create")
public ResponseEntity<String> createUser(@Validated(UserDTO.Create.class) @RequestBody UserDTO user) {return ResponseEntity.ok("按分組校驗通過");
}
四、校驗嵌套對象
public class OrderDTO {@NotNull@Valid // 注意:嵌套對象必須加 @Valid 才能觸發其內部校驗private UserDTO user;
}
五、處理校驗失敗異常
Spring Boot 默認拋出 MethodArgumentNotValidException
(@Valid)或 ConstraintViolationException
(@Validated)。
可以通過全局異常處理捕獲并格式化返回:
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<?> handleValidException(MethodArgumentNotValidException ex) {String errorMsg = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining("; "));return ResponseEntity.badRequest().body("參數錯誤:" + errorMsg);}
}
六、自定義校驗注解
1. 自定義注解:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {PhoneValidator.class})
public @interface Phone {String message() default "手機號格式不正確";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
2. 編寫校驗器:
public class PhoneValidator implements ConstraintValidator<Phone, String> {private static final Pattern PATTERN = Pattern.compile("^1[3-9]\\d{9}$");@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {return value != null && PATTERN.matcher(value).matches();}
}
3. 使用:
@Phone
private String phone;
七、常用校驗注解速查表
注解 | 功能說明 |
---|---|
@NotNull | 不能為 null |
@NotEmpty | 不能為 null 且長度 > 0 |
@NotBlank | 不能為 null 且去空格后長度 > 0 |
@Email | 郵箱格式 |
@Min | 最小值限制 |
@Max | 最大值限制 |
@Pattern | 正則校驗 |
@Size | 長度范圍校驗 |
@Future | 必須是未來時間 |
@Past | 必須是過去時間 |
八、注意事項與最佳實踐
- 嵌套校驗字段必須加
@Valid
。 @Validated
支持分組、@Valid
不支持。- 實體類字段建議使用包裝類型(如
Integer
而非int
),避免 null 時校驗器報錯。 - 參數校驗推薦配合統一響應結構,提升開發與調試體驗。