一、依賴配置
首先確保在?pom.xml
?中添加了以下依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
這個依賴包含了 Hibernate Validator(JSR-380 規范的實現)和必要的 Spring 驗證支持。
驗證執行流程:
-
當請求到達Controller方法時,Spring會檢查方法參數上的
@Valid
或@Validated
注解 -
觸發
MethodValidationInterceptor
攔截器 -
創建
Validator
實例并執行驗證 -
驗證器會遞歸檢查對象及其屬性上的所有約束注解
-
如果驗證失敗,收集所有違反的約束
二、基本驗證注解
以下是常用的驗證注解:
-
@NotNull
?- 值不能為 null -
@Null
?- 值必須為 null -
@AssertTrue
?- 值必須為 true -
@AssertFalse
?- 值必須為 false -
@Min(value)
?- 數字必須大于等于指定值 -
@Max(value)
?- 數字必須小于等于指定值 -
@DecimalMin(value)
?- 必須大于等于指定值(字符串形式表示) -
@DecimalMax(value)
?- 必須小于等于指定值(字符串形式表示) -
@Size(min, max)
?- 集合/字符串/數組大小必須在范圍內 -
@Digits(integer, fraction)
?- 數字格式檢查 -
@Past
?- 必須是過去的日期 -
@PastOrPresent
?- 必須是過去或現在的日期 -
@Future
?- 必須是將來的日期 -
@FutureOrPresent
?- 必須是將來或現在的日期 -
@Pattern(regex)
?- 必須匹配正則表達式 -
@Email
?- 必須是有效的郵箱格式 -
@Valid
?- 級聯驗證,用于驗證對象中的嵌套對象
三、使用示例
1. 在實體類中使用驗證注解
public class User {@NotNull(message = "用戶ID不能為空")private Long id;@NotBlank(message = "用戶名不能為空")@Size(min = 2, max = 20, message = "用戶名長度必須在2-20之間")private String username;@Email(message = "郵箱格式不正確")private String email;@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,}$", message = "密碼必須至少8個字符,包含大小寫字母和數字")private String password;@Min(value = 18, message = "年齡必須大于等于18")@Max(value = 100, message = "年齡必須小于等于100")private Integer age;@Past(message = "出生日期必須是過去的時間")private LocalDate birthday;// getters and setters
}
2. 在Controller中使用驗證
@RestController
@RequestMapping("/api/users")
public class UserController {@PostMappingpublic ResponseEntity<String> createUser(@Valid @RequestBody User user) {// 業務邏輯處理return ResponseEntity.ok("用戶創建成功");}@GetMapping("/{id}")public ResponseEntity<User> getUserById(@PathVariable @Min(1) Long id,@RequestParam(required = false) @Size(max = 100) String name) {// 業務邏輯處理return ResponseEntity.ok(new User());}
}
3. 處理驗證錯誤
當驗證失敗時,Spring 會拋出?MethodArgumentNotValidException
。可以全局處理這些異常:
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<ErrorResponse> handleValidationExceptions(MethodArgumentNotValidException ex) {List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();List<ErrorDetail> errorDetails = fieldErrors.stream().map(error -> new ErrorDetail(error.getField(),error.getRejectedValue(),error.getDefaultMessage())).collect(Collectors.toList());ErrorResponse response = new ErrorResponse("VALIDATION_FAILED","參數驗證失敗",errorDetails);return ResponseEntity.badRequest().body(response);}
}// 響應數據結構
public class ErrorResponse {private String code;private String message;private List<ErrorDetail> details;// 構造方法/getters/setters
}public class ErrorDetail {private String field;private Object rejectedValue;private String message;// 構造方法/getters/setters
}
響應示例
當驗證失敗時,返回的JSON結構如下:
{"code": "VALIDATION_FAILED","message": "參數驗證失敗","details": [{"field": "age","rejectedValue": 15,"message": "年齡必須大于等于18"},{"field": "email","rejectedValue": "invalid-email","message": "必須是有效的郵箱格式"}]
}