從零到掌握Spring Boot Validation 接口校驗(yàn)的詳細(xì)過程
在開發(fā) Web 應(yīng)用時(shí),數(shù)據(jù)校驗(yàn)是不可忽視的一部分。無論是注冊用戶信息、提交表單數(shù)據(jù),還是處理業(yè)務(wù)邏輯,數(shù)據(jù)的有效性和完整性都需要得到保證。Spring Boot 提供了強(qiáng)大的驗(yàn)證功能,基于 Hibernate Validator 框架,通過注解方式簡化了數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn)。本文將詳細(xì)介紹 Spring Boot 的 Validation 接口校驗(yàn)機(jī)制,包括其核心功能、常用注解、自定義校驗(yàn)、以及實(shí)際應(yīng)用場景。
1. 什么是 Spring Validation?
Spring Validation 是一個用于數(shù)據(jù)校驗(yàn)的框架,它基于 JSR-303(Bean Validation API) 和 Hibernate Validator 實(shí)現(xiàn)。通過在 JavaBean 的字段上添加特定的注解,可以定義數(shù)據(jù)的校驗(yàn)規(guī)則。Spring Boot 通過整合 Hibernate Validator,使得在 Web 應(yīng)用中使用數(shù)據(jù)校驗(yàn)變得更加簡單。
2. Spring Boot Validation 的核心功能
- 注解式校驗(yàn):通過注解定義數(shù)據(jù)校驗(yàn)規(guī)則。
- 自動化校驗(yàn):Spring Boot 提供了對校驗(yàn)的自動支持,無需手動編寫校驗(yàn)邏輯。
- 異常處理:Spring Boot 可以自動將校驗(yàn)失敗的錯誤信息返回給客戶端。
- 支持分組校驗(yàn):可以為不同的場景定義不同的校驗(yàn)分組。
- 支持自定義校驗(yàn):可以擴(kuò)展注解,定義自定義的校驗(yàn)邏輯。
3. 常用的校驗(yàn)注解
以下是 Spring Boot 中常用的校驗(yàn)注解:
注解 | 功能描述 |
---|---|
@NotNull | 確保字段不為 null |
@Null | 確保字段為 null |
@NotBlank | 確保字段不為空(字符串) |
@NotEmpty | 確保字段不為空(集合、數(shù)組) |
@Length | 確保字段的長度在指定范圍內(nèi) |
@Size | 確保字段的長度在指定范圍內(nèi)(適用于集合、數(shù)組、字符串) |
@Range | 確保字段的值在指定范圍內(nèi) |
@Min | 確保字段的值大于等于指定值 |
@Max | 確保字段的值小于等于指定值 |
@Email | 確保字段為有效的電子郵件地址 |
@Pattern | 確保字段的值匹配指定的正則表達(dá)式 |
@Past | 確保字段的值是過去的日期 |
@Future | 確保字段的值是未來的日期 |
4. Spring Boot Validation 的實(shí)現(xiàn)步驟
步驟 1:添加依賴
在 pom.xml
文件中添加以下依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
步驟 2:創(chuàng)建 JavaBean
創(chuàng)建一個需要校驗(yàn)的 JavaBean 類,并在字段上添加校驗(yàn)注解:
import jakarta.validation.constraints.*; public class User { @NotNull(message = "用戶名不能為空") @Size(min = 2, max = 10, message = "用戶名長度必須在2到10之間") private String username; @NotNull(message = "密碼不能為空") @NotBlank(message = "密碼不能為空") @Pattern(regexp = "^(?=.*\\d)(?=.*[A-Za-z])(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,20}$", message = "密碼格式不正確") private String password; @Email(message = "郵箱格式不正確") private String email; @Min(value = 18, message = "年齡必須大于等于18歲") private Integer age; public User() {} // Getters and Setters }
步驟 3:在控制器中使用 @Valid 注解
在控制器的參數(shù)中使用 @Valid
注解啟用校驗(yàn):
import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @RestController public class UserController { @PostMapping("/register") public ResponseEntity<?> register(@Valid @RequestBody User user) { // 業(yè)務(wù)邏輯 return ResponseEntity.ok("注冊成功"); } }
步驟 4:處理校驗(yàn)異常
Spring Boot 會自動將校驗(yàn)失敗的錯誤信息封裝到 MethodArgumentNotValidException
異常中??梢酝ㄟ^全局異常處理來統(tǒng)一返回錯誤信息:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; 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; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import java.util.HashMap; import java.util.Map; @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 new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } }
5. 自定義校驗(yàn)注解
如果內(nèi)置的校驗(yàn)注解無法滿足需求,可以通過自定義注解來擴(kuò)展校驗(yàn)功能。
自定義校驗(yàn)注解
import jakarta.validation.Constraint; import jakarta.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Constraint(validatedBy = {PhoneValidator.class}) @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Phone { String message() default "手機(jī)號格式不正確"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
自定義校驗(yàn)邏輯
import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; public class PhoneValidator implements ConstraintValidator<Phone, String> { @Override public void initialize(Phone constraintAnnotation) { } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null) { return false; } // 手機(jī)號正則表達(dá)式 String regex = "^1(3\\d|5[i-o]\\d|78\\d|4\\d)\\d{7}$"; return value.matches(regex); } }
使用自定義校驗(yàn)注解
@Phone(message = "手機(jī)號格式不正確") private String phone;
6. 分組校驗(yàn)和條件校驗(yàn)
分組校驗(yàn)
通過分組校驗(yàn),可以為不同的場景定義不同的校驗(yàn)規(guī)則。
public interface SaveGroup { } public interface UpdateGroup { } @NotNull(groups = SaveGroup.class) @Size(min = 2, max = 10, groups = {SaveGroup.class, UpdateGroup.class}) private String username;
在控制器中指定需要校驗(yàn)的分組:
@PostMapping("/save") public ResponseEntity<?> save(@Validated(SaveGroup.class) @RequestBody User user) { // 業(yè)務(wù)邏輯 return ResponseEntity.ok("保存成功"); }
條件校驗(yàn)
通過 @ScriptAssert
注解,可以基于腳本語言(如 JavaScript 或 Groovy)實(shí)現(xiàn)復(fù)雜的條件校驗(yàn)。
@ScriptAssert(lang = "javascript", script = "password.length >= 8 && password.match(/^(?=.*\\d)(?=.*[A-Za-z])(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,20}$/)") public class User { // 字段定義 }
7. 結(jié)合其他技術(shù)
1. 統(tǒng)一異常處理
通過全局異常處理,可以統(tǒng)一返回校驗(yàn)失敗的錯誤信息,提升用戶體驗(yàn)。
2. 日志記錄
通過 AOP(Aspect Oriented Programming),可以記錄校驗(yàn)失敗的日志,方便后續(xù)分析:
@Aspect @Component public class ValidationAspect { @Around("execution(* *(..)) && @annotation(org.springframework.web.bind.annotation.PostMapping)") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { try { Object[] args = joinPoint.getArgs(); if (args != null && args.length > 0) { for (Object arg : args) { if (arg != null && arg.getClass().getAnnotation(Valid.class) != null) { // 記錄日志 System.out.println("開始校驗(yàn)數(shù)據(jù):" + arg); } } } return joinPoint.proceed(); } catch (MethodArgumentNotValidException ex) { // 記錄校驗(yàn)失敗的日志 System.out.println("校驗(yàn)失?。? + ex.getBindingResult()); throw ex; } } }
8. 常見問題和解決方案
常見問題
- 校驗(yàn)注解不生效:
- 檢查是否添加了
spring-boot-starter-validation
依賴。 - 確保在控制器中使用了
@Valid
注解。
- 檢查是否添加了
- 錯誤信息不返回:
- 檢查是否實(shí)現(xiàn)了全局異常處理。
- 確保控制器的返回類型為
ResponseEntity
。
- 自定義校驗(yàn)注解不生效:
- 檢查自定義注解的
ConstraintValidator
是否正確實(shí)現(xiàn)。 - 確保自定義注解使用了
@Constraint
注解。
- 檢查自定義注解的
總結(jié)
Spring Boot 的 Validation 功能提供了一種簡單而強(qiáng)大的數(shù)據(jù)校驗(yàn)方式,通過注解式校驗(yàn)和自動化處理,能夠顯著提升開發(fā)效率和代碼質(zhì)量。結(jié)合 Hibernate Validator 的強(qiáng)大功能,開發(fā)者可以輕松實(shí)現(xiàn)復(fù)雜的校驗(yàn)邏輯,同時(shí)通過自定義校驗(yàn)注解和分組校驗(yàn),滿足不同的業(yè)務(wù)需求。
希望本文能幫助你在實(shí)際項(xiàng)目中更好地使用 Spring Boot 的 Validation 功能,提高代碼的健壯性和用戶體驗(yàn)!
到此這篇關(guān)于從零到掌握Spring Boot Validation 接口校驗(yàn)的詳細(xì)過程的文章就介紹到這了,更多相關(guān)Spring Boot Validation 接口校驗(yàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot + validation 接口參數(shù)校驗(yàn)的思路詳解
- Spring?Boot集成validation實(shí)現(xiàn)參數(shù)校驗(yàn)功能
- SpringBoot使用Validation包進(jìn)行輸入?yún)?shù)校驗(yàn)
- spring?boot?validation參數(shù)校驗(yàn)與分組嵌套各種類型及使用小結(jié)
- springboot中使用Hibernate-Validation校驗(yàn)參數(shù)詳解
- SpringBoot使用Validation進(jìn)行參數(shù)校驗(yàn)的示例詳解
- spring-boot-starter-validation?校驗(yàn)參數(shù)的實(shí)現(xiàn)
- spring boot輸入數(shù)據(jù)校驗(yàn)(validation)的實(shí)現(xiàn)過程
相關(guān)文章
微服務(wù)Spring?Boot?整合Redis?阻塞隊(duì)列實(shí)現(xiàn)異步秒殺下單思路詳解
這篇文章主要介紹了微服務(wù)Spring?Boot?整合Redis?阻塞隊(duì)列實(shí)現(xiàn)異步秒殺下單,使用阻塞隊(duì)列實(shí)現(xiàn)秒殺的優(yōu)化,采用異步秒殺完成下單的優(yōu)化,本文給大家分享詳細(xì)步驟及實(shí)現(xiàn)思路,需要的朋友可以參考下2022-10-10idea中項(xiàng)目前端網(wǎng)頁圖標(biāo)不顯示的原因及解決
這篇文章主要介紹了idea中項(xiàng)目前端網(wǎng)頁圖標(biāo)不顯示的原因及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07IDEA 的基本介紹使用及斷點(diǎn)調(diào)試技巧
IDEA 是 JetBrains 公司的產(chǎn)品,總部位于捷克的首都布拉格,IDEA在業(yè)界被公認(rèn)為最好的 Java 開發(fā)工具,今天通過本文給大家介紹IDEA 的基本介紹使用及斷點(diǎn)調(diào)試技巧,感興趣的朋友跟隨小編一起看看吧2021-11-11SpringBoot教程_創(chuàng)建第一個SpringBoot項(xiàng)目
這篇文章主要介紹了SpringBoot教程_創(chuàng)建第一個SpringBoot項(xiàng)目,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06Java 面向?qū)ο笾^承篇詳解原理與特點(diǎn)
繼承是java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因?yàn)樗试S創(chuàng)建分等級層次的類。繼承就是子類繼承父類的特征和行為,使得子類對象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為2021-10-10Java實(shí)戰(zhàn)項(xiàng)目 圖書管理系統(tǒng)
這篇文章主要介紹了使用java SSM jsp mysql maven設(shè)計(jì)實(shí)現(xiàn)的精品圖書管理系統(tǒng),是一個很好的實(shí)例,對大家的學(xué)習(xí)和工作具有借鑒意義,建議收藏一下2021-09-09spring使用ehcache實(shí)現(xiàn)頁面緩存示例
這篇文章主要介紹了spring使用ehcache實(shí)現(xiàn)頁面緩存示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02SpringCloud Feign Jackson自定義配置方式
這篇文章主要介紹了SpringCloud Feign Jackson自定義配置方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03java swing中實(shí)現(xiàn)拖拽功能示例
這篇文章主要介紹了java swing中實(shí)現(xiàn)拖拽功能示例,需要的朋友可以參考下2014-04-04