🛠? 一、JSR 303是什么?
JSR 303(Java Specification Requests 303)是Java EE 6的子規范,全稱??Bean Validation??。它通過注解方式對JavaBean的屬性值進行標準化校驗,例如檢查非空、長度、格式等規則。其參考實現是??Hibernate Validator??(與Hibernate ORM無關)
??核心價值??:
? 將校驗邏輯從業務代碼剝離,提升代碼可維護性
? 統一校驗規則,避免重復編碼
? 支持編譯時和運行時校驗,增強數據安全性(防止惡意繞過前端校驗)
?? 二、快速入門:基礎使用
1?? 環境搭建
- ??Spring Boot項目??:添加依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- ??非Spring項目??:需手動引入
validation-api
和hibernate-validator
2?? 常用內置注解
注解 | 適用類型 | 說明 | 示例 |
---|---|---|---|
@NotNull | 任意 | 值不能為null | @NotNull(message="ID不能為空") |
@NotBlank | String | 非null且去除空格后長度>0 | @NotBlank(message="用戶名必填") |
@Size | 集合/String | 長度在指定范圍內 | @Size(min=6, max=20, message="密碼需6-20位") |
@Email | String | 郵箱格式校驗 | @Email(message="郵箱格式無效") |
@Pattern | String | 正則表達式匹配 | @Pattern(regexp="^1[3-9]\\d{9}$", message="手機號格式錯誤") |
@Min /@Max | 數字類型 | 數值范圍限制 | @Min(value=18, message="年齡需≥18") |
3?? 在Controller中使用
通過@Valid
或@Validated
觸發校驗:
@PostMapping("/user")
public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO user) {// 校驗通過才執行業務邏輯return ResponseEntity.ok("創建成功");
}
- 校驗失敗會拋出
MethodArgumentNotValidException
,需全局異常處理
? 三、進階技巧
1?? 分組校驗
解決同一字段在不同場景(如新增/修改)下的差異化校驗需求:
// 定義分組接口
public interface AddGroup {}
public interface UpdateGroup {}// 實體類中使用
public class User {@Null(groups = AddGroup.class, message = "新增時ID必須為空")@NotNull(groups = UpdateGroup.class, message = "修改時ID不能為空")private Long id;
}// Controller指定分組
@PostMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody User user) {// ...
}
注:未分組的注解在分組校驗中不生效
2?? 自定義校驗
??步驟??:
- ??定義注解??:
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = ListValueConstraintValidator.class) public @interface ListValue {String message() default "值不在可選范圍內";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};int[] vals() default {}; // 允許的值列表,如[0,1] }
- ??實現校驗器??:
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {private Set<Integer> set = new HashSet<>();@Overridepublic void initialize(ListValue constraintAnnotation) {for (int val : constraintAnnotation.vals()) {set.add(val);}}@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {return set.contains(value);} }
- ??使用自定義注解??:
@ListValue(vals = {0, 1}, message = "狀態只能是0或1") private Integer status;
💎 四、常見問題
-
??Q:
@Valid
?vs?@Validated
???@Valid
(JSR標準):不支持分組,可嵌套校驗字段。@Validated
(Spring擴展):支持分組,不可用于字段
-
??Q:校驗失敗如何獲取具體錯誤???
在Controller參數中添加BindingResult result
,通過result.getFieldErrors()
遍歷錯誤詳情 -
??Q:為什么int類型推薦用
Integer
???
@Min
等注解在基本類型(如int
)上無法處理空值,而Integer
可兼容null
校驗
📚 總結
JSR 303通過??聲明式注解??簡化數據校驗。初學者可逐步掌握:
1?? 基礎注解 → 2?? Controller集成 → 3?? 分組/自定義校驗 → 4?? 全局異常處理
結合Spring生態(如Spring MVC)能極大提升開發效率和系統健壯性
更多實踐參考:Hibernate Validator文檔或Spring官方教程。