Java?JDK?Validation?注解解析與使用方法驗(yàn)證
Jakarta Validation(原 JSR-380,也稱為 Bean Validation 2.0)是 Java 中用于驗(yàn)證對(duì)象數(shù)據(jù)的標(biāo)準(zhǔn) API。
它提供了一套注解和接口,用于聲明和執(zhí)行驗(yàn)證規(guī)則。
位于 jakarta.validation。
核心概念
1. 主要注解
基本約束注解
| 注解 | 作用 |
|---|---|
@NotNull | 驗(yàn)證值不為 null |
@Null | 驗(yàn)證值必須為 null |
@AssertTrue | 驗(yàn)證布爾值為 true |
@AssertFalse | 驗(yàn)證布爾值為 false |
@Min(value) | 驗(yàn)證數(shù)字不小于指定值 |
@Max(value) | 驗(yàn)證數(shù)字不大于指定值 |
@DecimalMin(value) | 驗(yàn)證數(shù)字不小于指定值(字符串形式) |
@DecimalMax(value) | 驗(yàn)證數(shù)字不大于指定值(字符串形式) |
@Size(min, max) | 驗(yàn)證集合/數(shù)組/字符串大小在范圍內(nèi) |
@Digits(integer, fraction) | 驗(yàn)證數(shù)字格式 |
@Past | 驗(yàn)證日期是過(guò)去的 |
@PastOrPresent | 驗(yàn)證日期是過(guò)去或現(xiàn)在 |
@Future | 驗(yàn)證日期是將來(lái)的 |
@FutureOrPresent | 驗(yàn)證日期是將來(lái)或現(xiàn)在 |
@Pattern(regex) | 驗(yàn)證字符串匹配正則表達(dá)式 |
@Email | 驗(yàn)證字符串是有效的電子郵件格式 |
其他常用注解
| 注解 | 作用 |
|---|---|
@Valid | 級(jí)聯(lián)驗(yàn)證對(duì)象中的屬性 |
@NotEmpty | 驗(yàn)證字符串/集合不為 null 且不為空 |
@NotBlank | 驗(yàn)證字符串不為 null 且至少包含一個(gè)非空白字符 |
@Positive | 驗(yàn)證數(shù)字為正數(shù) |
@PositiveOrZero | 驗(yàn)證數(shù)字為正數(shù)或零 |
@Negative | 驗(yàn)證數(shù)字為負(fù)數(shù) |
@NegativeOrZero | 驗(yàn)證數(shù)字為負(fù)數(shù)或零 |
2. 核心接口
Validator: 執(zhí)行驗(yàn)證的主要接口ConstraintValidator: 自定義約束驗(yàn)證器接口ConstraintViolation: 表示驗(yàn)證失敗的結(jié)果ConstraintValidatorContext: 自定義驗(yàn)證器的上下文
使用方法
1. 基本使用
添加依賴 (Maven)
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.2</version>
</dependency>
<!-- 實(shí)現(xiàn) (如 Hibernate Validator) -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.1.Final</version>
</dependency>定義驗(yàn)證對(duì)象
public class User {
@NotNull(message = "用戶名不能為空")
@Size(min = 3, max = 20, message = "用戶名長(zhǎng)度必須在3-20之間")
private String username;
@Email(message = "郵箱格式不正確")
private String email;
@Min(value = 18, message = "年齡必須大于18歲")
private int age;
// getters and setters
}執(zhí)行驗(yàn)證
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
User user = new User();
user.setUsername("ab"); // 太短
user.setEmail("invalid-email");
user.setAge(17);
Set<ConstraintViolation<User>> violations = validator.validate(user);
for (ConstraintViolation<User> violation : violations) {
System.out.println(violation.getPropertyPath() + ": " + violation.getMessage());
}2. 在 Spring Boot 中使用
Spring Boot 自動(dòng)集成了 Bean Validation,可以直接使用:
控制器驗(yàn)證
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public ResponseEntity<String> createUser(@Valid @RequestBody User user) {
// 如果驗(yàn)證失敗,會(huì)拋出MethodArgumentNotValidException
return ResponseEntity.ok("用戶創(chuàng)建成功");
}
}全局異常處理
@ControllerAdvice
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 ResponseEntity.badRequest().body(errors);
}
}3. 自定義驗(yàn)證注解
定義注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface PhoneNumber {
String message() default "無(wú)效的電話號(hào)碼";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}實(shí)現(xiàn)驗(yàn)證器
public class PhoneNumberValidator implements ConstraintValidator<PhoneNumber, String> {
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true; // 使用@NotNull處理null值
}
return PHONE_PATTERN.matcher(value).matches();
}
}使用自定義注解
public class ContactInfo {
@PhoneNumber
private String phone;
// getter and setter
}高級(jí)特性
1. 分組驗(yàn)證
public interface BasicInfo {}
public interface AdvancedInfo {}
public class User {
@NotNull(groups = BasicInfo.class)
private String username;
@Email(groups = AdvancedInfo.class)
private String email;
}
// 使用分組驗(yàn)證
Set<ConstraintViolation<User>> violations = validator.validate(user, BasicInfo.class);2. 級(jí)聯(lián)驗(yàn)證
public class Order {
@Valid
private List<OrderItem> items;
}
public class OrderItem {
@NotNull
private String productId;
@Min(1)
private int quantity;
}3. 自定義消息
可以使用表達(dá)式和EL表達(dá)式:
@Size(min = 6, max = 20, message = "密碼長(zhǎng)度必須在 {min} 到 {max} 之間")
private String password;4. 方法驗(yàn)證
驗(yàn)證方法參數(shù)和返回值:
public class UserService {
@Validated
public void createUser(@Valid User user) {
// ...
}
@Valid
public User getUser(@NotNull Long id) {
// ...
}
}最佳實(shí)踐
- 合理選擇驗(yàn)證級(jí)別:在DTO層進(jìn)行基本驗(yàn)證,在業(yè)務(wù)層進(jìn)行復(fù)雜驗(yàn)證
- 使用適當(dāng)?shù)南ⅲ禾峁┣逦⒂脩粲押玫腻e(cuò)誤消息
- 組合使用注解:如
@NotNull+@Size比單獨(dú)使用更安全 - 避免過(guò)度驗(yàn)證:只在必要的地方添加驗(yàn)證
- 考慮性能:大量驗(yàn)證可能影響性能,特別是在批量操作中
Jakarta Validation 提供了一種聲明式、標(biāo)準(zhǔn)化的方式來(lái)驗(yàn)證Java對(duì)象,與框架無(wú)關(guān),可以方便地集成到各種Java應(yīng)用中。
到此這篇關(guān)于Java JDK Validation 注解解析與使用的文章就介紹到這了,更多相關(guān)Java JDK Validation 注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringAOP事務(wù)配置語(yǔ)法及實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了SpringAOP事務(wù)配置語(yǔ)法及實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié)
這篇文章主要為大家介紹了Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
詳解Spring Boot中如何自定義SpringMVC配置
這篇文章主要給大家介紹了關(guān)于Spring Boot中如何自定義SpringMVC配置的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-09-09
關(guān)于使用Lambda表達(dá)式簡(jiǎn)化Comparator的使用問(wèn)題
這篇文章主要介紹了關(guān)于使用Lambda表達(dá)式簡(jiǎn)化Comparator的使用問(wèn)題,文中圖文講解了Comparator對(duì)象的方法,需要的朋友可以參考下2023-04-04
Java實(shí)現(xiàn)圖章或簽名插在pdf的固定位置
使用Java技術(shù)在word轉(zhuǎn)換成pdf過(guò)程中實(shí)現(xiàn)將圖章或者簽名插入在pdf中,并生成帶圖章或者簽名的pdf,來(lái)完成某些特定場(chǎng)景的需求,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-10-10

