spring?參數(shù)校驗Validation示例詳解
前言
在實際開發(fā)中,我們無法保證客戶端傳來的請求都是合法的。比如一些要求必傳的參數(shù)沒有傳遞,傳來的參數(shù)長度不符合要求等,這種時候如果放任不管,繼續(xù)執(zhí)行后續(xù)業(yè)務(wù)邏輯,很有可能就會出現(xiàn)意想不到的bug。
有人可能會說,這不是前端的問題嗎,讓前端校驗去。話是這么說,但我們也不能前端校驗百分百不會出現(xiàn)問題。并且有些請求可能也不是正規(guī)通過客戶端發(fā)來的,可能是黑客惡意攻擊,又或是通過Postman等發(fā)來的,這些請求就不一定會“合法”了。
因此,對客戶端傳來的每個請求都進(jìn)行必要的參數(shù)校驗是十分重要的。而很多簡單的校驗如果都需要程序員自己去寫的話,就會導(dǎo)致代碼過于冗長、繁瑣。為了讓校驗更加簡潔明了,Spring為我們提供了Validation工具類來提供各種校驗方法。
一、Validation常見的校驗注解
空校驗注解:
@Null:被注釋的元素必須為null。@NotNull:被注釋的元素必須不為null。@NotBlank:被注釋的字符串去掉前后空格后長度必須非零。@NotEmpty:被注釋的字符串、集合或數(shù)組不能為空(字符串長度非零、集合大小非零)。
布爾校驗注解:
@AssertTrue:被注釋的元素必須為true。@AssertFalse:被注釋的元素必須為false。
日期校驗注解:
@Past:被注釋的元素必須是一個過去的日期。@Future:被注釋的元素必須是一個將來的日期。
數(shù)字校驗注解:
@Min(value):被注釋的元素必須是一個數(shù)字,其值必須大于等于指定的最小值。@Max(value):被注釋的元素必須是一個數(shù)字,其值必須小于等于指定的最大值。@DecimalMin(value):被注釋的元素必須是一個數(shù)字,其值必須大于等于指定的最小值。@DecimalMax(value):被注釋的元素必須是一個數(shù)字,其值必須小于等于指定的最大值。
長度校驗注解:
@Size(max, min):被注釋的元素(如字符串、集合、數(shù)組)的大小必須在指定的范圍內(nèi)。
模式匹配校驗注解:
@Pattern(regexp):被注釋的元素必須符合指定的正則表達(dá)式。
郵箱校驗注解:
@Email:被注釋的元素必須是電子郵箱地址。
范圍校驗注解:
@Range(min, max):被注釋的元素必須在合適的范圍內(nèi)。
二、Validation的簡單應(yīng)用
首先我們需要導(dǎo)入Validation的依賴:
<!--validation依賴,負(fù)責(zé)參數(shù)校驗--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
接著在需要使用校驗的類上添加@Validation注解

接著主要有兩種方式使用校驗注解:
1、直接在對應(yīng)參數(shù)上加上注解
@RestController
@RequestMapping("/user")
@Validation
public class UserController {
@RequestMapping("/login")
public Result login(@Size(max = 12,min = 4) String username, @Pattern(regexp = "^\\S{5,16}$") String password){
//登錄
return Result.success();
}
}2、實體類添加校驗
對于一些實體類來說,直接在參數(shù)上加注解就不太可取了,程序會無法定位到指定參數(shù)。
需要再實體類內(nèi)部對應(yīng)的變量上添加注解:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Category {
@NotNull
private Integer id;//主鍵ID
@NotEmpty
private String categoryName;//分類名稱
@NotEmpty
private String categoryAlias;//分類別名
private Integer createUser;//創(chuàng)建人ID
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;//創(chuàng)建時間
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;//更新時間
}接著在使用實體類的地方加上 @Validated 注解,就能讓這些校驗生效了:
@PutMapping("/update")
public Result update(@RequestBody @Validated User user){
//業(yè)務(wù)邏輯
return Result.success();
}三、分組校驗
前面我們介紹了如何在實體類中添加校驗注解。但是,事實上在實現(xiàn)不同功能時,對同一個實體類的校驗規(guī)則可能是會有差異的。
比如在添加用戶的場景下,用戶的id值就是在存入數(shù)據(jù)庫后生成的,在參數(shù)傳遞時自然就不是必傳項;而在更新用戶的場景下,我們需要通過id定位指定用戶,完成信息更新操作,這時在參數(shù)傳遞時id就是必傳項了。
這樣,對id值的校驗就會產(chǎn)生沖突了。如果將id設(shè)定為必傳值,那么就會導(dǎo)致添加用戶的操作可能出現(xiàn)錯誤。不把id設(shè)定為必傳值,更新用戶的操作又會出現(xiàn)錯誤。
為了應(yīng)對這一問題,就可以對校驗項進(jìn)行分組歸類。具體操作步驟如下:
在實體類內(nèi)部定義相應(yīng)組別接口:
public class User {
//各成員變量
//添加用戶類分組
public interface Add extends Default {
}
//更新用戶類分組
public interface Update extends Default{
}
}注意:如果沒有手動對校驗項進(jìn)行分組,其默認(rèn)就在 Default 組
對校驗項進(jìn)行分組,只需要通過groups屬性指定組別即可:
@NotNull(groups = Update.class)
接著在校驗時指定對應(yīng)的分組即可:
@PutMapping
public Result update(@RequestBody @Validated(User.Update.class) User user){
//業(yè)務(wù)邏輯
return Result.success();
}@PostMapping
public Result add(@RequestBody @Validated(User.Add.class) User user){
//業(yè)務(wù)邏輯
return Result.success();
}這樣就能實現(xiàn)不同業(yè)務(wù)場景下的多樣化校驗了。
四、自定義校驗
實際開發(fā)中的校驗規(guī)則可能是五花八門的,但官方提供的校驗注解就這么多,很多時候并不能滿足我們的校驗需求。這時候就需要通過自定義校驗注解來實現(xiàn)個性化的校驗了。
首先需要定義一個注解:
@Documented //元注解
@Target(ElementType.FIELD) //元注解
@Retention(RetentionPolicy.RUNTIME) //元注解
@Constraint(validatedBy = {/*校驗規(guī)則*/}) //自定義校驗規(guī)則
public @interface State {
//提供校驗失敗后的提示信息
String message() default "state參數(shù)的值只能是已發(fā)布或草稿";
//指定分組
Class<?>[] groups() default {};
//負(fù)載 獲取到State注解的附加信息
Class<? extends Payload>[] payload() default {};
}接著定義一個類去實現(xiàn) ConstraintValidator 接口,并實現(xiàn) isValid 方法:
public class StateValidation implements ConstraintValidator<State,String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
//返回true表示校驗通過,返回false則表示校驗不通過
if(value==null) return false;
if(value.equals("已發(fā)布")||value.equals("草稿"))return true;
return false;
}
}然后就要在之前定義的注解中的@Constraint中填入自定義類:
@Constraint(validatedBy = {StateValidation.class}) //自定義校驗規(guī)則
接著就可以像使用其它校驗注解一樣來使用自己自定義的注解了:

那么本篇文章就到此為止了,如果覺得這篇文章對你有幫助的話,可以點一下關(guān)注和點贊來支持作者哦。如果有什么講的不對的地方歡迎在評論區(qū)指出,希望能夠和你們一起進(jìn)步?
到此這篇關(guān)于spring 參數(shù)校驗Validation的文章就介紹到這了,更多相關(guān)spring 參數(shù)校驗Validation內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)的連接oracle/mysql數(shù)據(jù)庫功能簡單示例【附oracle+mysql數(shù)據(jù)庫驅(qū)動包】
這篇文章主要介紹了java實現(xiàn)的連接oracle/mysql數(shù)據(jù)庫功能,結(jié)合實例形式分析了java基于jdbc連接Oracle與mysql的相關(guān)操作技巧,并附帶完整實例代碼與oracle+mysql數(shù)據(jù)庫驅(qū)動包供讀者下載參考,需要的朋友可以參考下2017-10-10
SpringBoot整合PageHelper分頁無效的常見原因分析
這篇文章主要介紹了SpringBoot整合PageHelper分頁無效的常見原因分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
Flink結(jié)合Kafka實現(xiàn)通用流式數(shù)據(jù)處理
這篇文章將和大家一起深入探討Flink和Kafka的關(guān)系以及它們在數(shù)據(jù)流處理中的應(yīng)用,并提供一些最佳實踐和實際案例,希望對大家有一定的幫助2025-03-03
java 方法泛型入?yún)和String的重載關(guān)系詳解
這篇文章主要介紹了java 方法泛型入?yún)和String的重載關(guān)系詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
springBoot集成redis(jedis)的實現(xiàn)示例
Redis是我們Java開發(fā)中,使用頻次非常高的一個nosql數(shù)據(jù)庫,本文主要介紹了springBoot集成redis(jedis)的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-09-09
Java 實用工具類Spring 的 StopWatch常用方法
StopWatch 是 Spring 框架中極其實用的開發(fā)輔助工具,它為性能分析和調(diào)試提供了輕量但強大的能力,使用簡單、無需復(fù)雜配置,本文給大家介紹Java 實用工具類Spring 的 StopWatch常用方法,感興趣的朋友一起看看吧2025-04-04

