如何在Spring Boot 項目中自定義 Validation 注解
在Spring Boot項目中自定義Validation注解,可按以下步驟實現(xiàn),以手機號格式校驗(支持多地區(qū))為例:
一、定義自定義注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.FIELD, ElementType.PARAMETER}) // 作用于字段和方法參數(shù)
@Retention(RetentionPolicy.RUNTIME) // 運行時生效
@Constraint(validatedBy = PhoneValidator.class) // 關聯(lián)校驗器
public @interface Phone {
String message() default "手機號格式錯誤"; // 錯誤提示
Class<?>[] groups() default {}; // 分組校驗(如新增、更新)
Class<? extends Payload>[] payload() default {}; // 負載信息(可選)
String region() default "CN"; // 自定義屬性:地區(qū)(默認中國)
}二、實現(xiàn)校驗邏輯(ConstraintValidator)
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PhoneValidator implements ConstraintValidator<Phone, String> {
private String region; // 存儲注解的region屬性
@Override
public void initialize(Phone constraintAnnotation) {
this.region = constraintAnnotation.region(); // 初始化,獲取地區(qū)配置
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) return true; // 允許為空(若必填需額外處理,如@NotBlank配合使用)
// 根據(jù)地區(qū)校驗格式
switch (region) {
case "CN": // 中國手機號:11位,以1開頭,第二位3-9
return value.matches("^1[3-9]\\d{9}$");
case "US": // 美國手機號:+1開頭,后跟10位數(shù)字
return value.matches("^\\+1\\d{10}$");
default:
return false; // 未知地區(qū),校驗失敗
}
}
}三、應用自定義注解
1. 在DTO中使用
public class UserDTO {
@NotBlank
private String username;
@Phone(region = "CN") // 校驗中國手機號
private String phone;
// 若需校驗美國手機號,可設置region="US"
// @Phone(region = "US")
// private String usPhone;
// getters/setters
}2. 在Controller中觸發(fā)校驗
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
@PostMapping("/register")
public String register(@Validated @RequestBody UserDTO dto) {
// 校驗通過,執(zhí)行注冊邏輯
return "注冊成功";
}
}四、處理校驗異常(全局異常處理器)
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationError(MethodArgumentNotValidException ex) {
BindingResult result = ex.getBindingResult();
StringBuilder errorMsg = new StringBuilder();
for (FieldError error : result.getFieldErrors()) {
errorMsg.append(error.getField()).append(": ").append(error.getDefaultMessage()).append("; ");
}
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse(HttpStatus.BAD_REQUEST.value(), errorMsg.toString()));
}
static class ErrorResponse {
private int code;
private String message;
public ErrorResponse(int code, String message) {
this.code = code;
this.message = message;
}
// getters
}
}五、擴展功能
1. 分組校驗(如新增和更新場景)
// 定義分組接口
public interface CreateGroup {}
public interface UpdateGroup {}
// 在DTO中指定分組
@Phone(region = "CN", groups = CreateGroup.class) // 新增時校驗手機號
private String phone;
// Controller中使用分組
@PostMapping("/create")
public String create(@Validated(CreateGroup.class) @RequestBody UserDTO dto) { ... }
@PutMapping("/update")
public String update(@Validated(UpdateGroup.class) @RequestBody UserDTO dto) { ... }2. 國際化錯誤消息
在src/main/resources下創(chuàng)建ValidationMessages.properties:
Phone.message=手機號格式錯誤(中文) Phone.message_en=Invalid phone number format(英文)
Spring Boot會根據(jù)Accept-Language頭自動匹配語言。
3. 復雜業(yè)務校驗(如手機號唯一性)
// 校驗器中注入Service(需將校驗器標記為@Component,由Spring管理)
@Component
public class PhoneValidator implements ConstraintValidator<Phone, String> {
@Autowired
private UserService userService; // 假設UserService提供手機號唯一性查詢
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 先校驗格式,再校驗唯一性
if (!isFormatValid(value)) return false;
return !userService.existsByPhone(value); // 假設existsByPhone查詢數(shù)據(jù)庫
}
private boolean isFormatValid(String value) {
// 復用之前的格式校驗邏輯
return value.matches("^1[3-9]\\d{9}$");
}
}六、驗證效果
- 合法請求:
phone=13812345678,校驗通過,正常處理。 - 非法請求:
phone=123(格式錯誤),返回:{ "code": 400, "message": "phone: 手機號格式錯誤; " }
總結
自定義Validation注解的關鍵步驟為:
- 定義注解:通過
@Constraint關聯(lián)校驗器,設置屬性(如地區(qū)、錯誤消息)。 - 實現(xiàn)校驗邏輯:在
ConstraintValidator中編寫具體規(guī)則(格式、唯一性等)。 - 應用注解:在DTO/參數(shù)上標注,結合
@Validated觸發(fā)校驗。 - 處理異常:通過全局異常處理器返回標準化錯誤,提升用戶體驗。
這種方式可靈活擴展Spring Boot的校驗能力,滿足復雜業(yè)務需求(如多地區(qū)格式、業(yè)務規(guī)則校驗),確保輸入數(shù)據(jù)的合法性,是微服務架構中參數(shù)校驗的重要實踐。
到此這篇關于聊一聊在 Spring Boot 項目中自定義 Validation 注解的文章就介紹到這了,更多相關Spring Boot 自定義 Validation 注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Java中spring boot validation自定義注解使用方式
- SpringBoot使用Validation包進行輸入?yún)?shù)校驗
- SpringBoot Validation入?yún)⑿r瀲H化的項目實踐
- spring?boot?validation參數(shù)校驗與分組嵌套各種類型及使用小結
- springboot中使用Hibernate-Validation校驗參數(shù)詳解
- SpringBoot使用Validation進行參數(shù)校驗的示例詳解
- Spring?Boot之Validation自定義實現(xiàn)方式的總結
- spring-boot-starter-validation?校驗參數(shù)的實現(xiàn)
- SpringBoot之groups應對不同的Validation規(guī)則自定義方式
相關文章
Java實現(xiàn)復雜查詢優(yōu)化的7個技巧小結
在Java項目中,復雜查詢是開發(fā)者面臨的“硬骨頭”,本文將通過 7個實戰(zhàn)技巧,結合 代碼示例 和 性能對比,手把手教你如何讓復雜查詢變得優(yōu)雅,大家可以根據(jù)需求進行選擇2025-08-08
深入探究Java中的HashMap為什么會產(chǎn)生死循環(huán)
HashMap?死循環(huán)發(fā)生在?JDK?1.8?之前的版本中,這篇文章主要來和大家深入探究一下為什么Java中HashMap會產(chǎn)生死循環(huán),感興趣的小伙伴可以了解一下2023-05-05

