關于javax.validation.constraints的超詳細說明
前言
以下是關于 javax.validation.constraints(現為 ?Jakarta Bean Validation)的詳細說明,涵蓋核心注解、使用場景、代碼示例及最佳實踐:
一、javax.validation.constraints 是什么?
- ?作用?:提供一組標準注解,用于對 Java Bean 的字段或方法參數進行數據校驗(如非空、長度、范圍等)。
- ?規(guī)范演進?:
- Java EE 時期:包名為
javax.validation.constraints。 - Jakarta EE 9+:包名遷移為
jakarta.validation.constraints(需注意依賴兼容性)。
- Java EE 時期:包名為
二、核心注解列表及用法
1. 常用注解
| ?注解? | ?校驗規(guī)則? | ?支持類型? |
|---|---|---|
@NotNull | 值不能為 null | 任意類型 |
@NotBlank | 字符串不能為空或純空格 | String |
@NotEmpty | 集合/數組/字符串不能為空(長度 > 0) | Collection, String 等 |
@Size(min, max) | 元素數量或字符串長度在指定范圍內 | 集合、數組、字符串 |
@Min(value) | 數值必須 ≥ 指定最小值 | 數值類型(int, long 等) |
@Max(value) | 數值必須 ≤ 指定最大值 | 同上 |
@DecimalMin(value) | 數值必須 ≥ 指定最小值(字符串形式,支持精度) | BigDecimal, String 等 |
@DecimalMax(value) | 數值必須 ≤ 指定最大值(字符串形式,支持精度) | 同上 |
@Digits(integer, fraction) | 數值整數部分最多 integer 位,小數部分最多 fraction 位 | 數值類型 |
@Pattern(regexp) | 字符串必須匹配正則表達式 | String |
@Email | 字符串必須是合法郵箱格式 | String |
@Positive / @PositiveOrZero | 數值必須為正數或零 | 數值類型 |
@Negative / @NegativeOrZero | 數值必須為負數或零 | 數值類型 |
@Future / @FutureOrPresent | 日期必須在未來(或包含當前) | Date, LocalDate 等 |
@Past / @PastOrPresent | 日期必須在過去(或包含當前) | 同上 |
2. 注解示例代碼
public class User {
@NotBlank(message = "用戶名不能為空")
private String username;
@Email(message = "郵箱格式無效")
private String email;
@Size(min = 6, max = 20, message = "密碼長度需在6-20位之間")
private String password;
@Min(value = 18, message = "年齡必須≥18歲")
@Max(value = 100, message = "年齡必須≤100歲")
private Integer age;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手機號格式無效")
private String phone;
}三、集成到 Spring Boot 中的步驟
1. 添加依賴
<!-- Spring Boot 2.x 使用 javax.validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Jakarta EE 9+ 使用 jakarta.validation -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.2</version>
</dependency>2. 在 Controller 中觸發(fā)校驗
使用 @Valid 或 @Validated 注解觸發(fā)校驗:
@PostMapping("/users")
public ResponseEntity<?> createUser(@RequestBody @Valid User user) {
// 校驗通過后執(zhí)行業(yè)務邏輯
return ResponseEntity.ok("用戶創(chuàng)建成功");
}3. 處理校驗異常
通過 @ExceptionHandler 捕獲 MethodArgumentNotValidException:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationException(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 ResponseEntity.badRequest().body(errors);
}
}四、高級用法
1. 分組校驗
通過分組接口實現不同場景下的差異化校驗:
// 定義分組接口
public interface CreateGroup {}
public interface UpdateGroup {}
public class User {
@NotNull(groups = UpdateGroup.class)
private Long id;
@NotBlank(groups = {CreateGroup.class, UpdateGroup.class})
private String name;
}
// 在 Controller 中指定分組
@PostMapping("/users")
public ResponseEntity<?> createUser(@RequestBody @Validated(CreateGroup.class) User user) { ... }2. 自定義校驗注解
實現自定義校驗邏輯(如密碼強度校驗):
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface StrongPassword {
String message() default "密碼必須包含大小寫字母和數字";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class PasswordValidator implements ConstraintValidator<StrongPassword, String> {
@Override
public boolean isValid(String password, ConstraintValidatorContext context) {
return password.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).+$");
}
}3. 級聯校驗
校驗對象內的嵌套對象:
public class Order {
@Valid
private List<@Valid Product> products; // 校驗每個 Product 的字段
}五、校驗失敗的錯誤消息定制
1. 默認消息模板
每個注解的 message 屬性支持占位符:
@Size(min = 6, max = 20, message = "密碼長度需在{min}-{max}位之間")
private String password;2. 國際化消息
在 messages.properties 或 ValidationMessages.properties 中定義:
user.email.invalid=郵箱格式無效
注解中使用:
@Email(message = "{user.email.invalid}")
private String email;六、常見問題與解決方案
| ?問題? | ?解決方案? |
|---|---|
| 校驗未生效 | 檢查是否添加了 @Valid 或 @Validated 注解;確認依賴已正確引入 |
| 嵌套對象校驗失敗 | 在嵌套對象字段上添加 @Valid 注解 |
| 分組校驗不生效 | 在 @Validated 注解中明確指定分組接口 |
| 自定義校驗器未觸發(fā) | 確認 @Constraint(validatedBy = MyValidator.class) 并實現 ConstraintValidator |
七、總結
- ?核心價值?:通過聲明式注解簡化數據校驗邏輯,減少樣板代碼。
- ?最佳實踐?:
- 優(yōu)先使用標準注解,避免重復造輪子。
- 結合分組校驗實現多場景復用。
- 統一處理校驗異常,返回清晰的錯誤信息。
- ?擴展性?:通過自定義注解和校驗器滿足復雜業(yè)務需求。
到此這篇關于關于javax.validation.constraints超詳細說明的文章就介紹到這了,更多相關javax.validation.constraints說明內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot項目啟動時提示程序包不存在和找不到符號的處理方法
最近接手同事開發(fā)的一個Springboot工作項目,從svn上整體拉取下來后,構建完成后,啟動的時候遇到了程序包找不到的情況,所以本文記錄了SpringBoot項目啟動時提示程序包不存在和找不到符號的處理方法,需要的朋友可以參考下2024-05-05
springboot集成junit編寫單元測試實戰(zhàn)
在做單元測試時,代碼覆蓋率常常被拿來作為衡量測試好壞的指標,本文主要介紹了springboot集成junit編寫單元測試實戰(zhàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02

