spring?參數(shù)校驗(yàn)Validation示例詳解
前言
在實(shí)際開發(fā)中,我們無法保證客戶端傳來的請求都是合法的。比如一些要求必傳的參數(shù)沒有傳遞,傳來的參數(shù)長度不符合要求等,這種時(shí)候如果放任不管,繼續(xù)執(zhí)行后續(xù)業(yè)務(wù)邏輯,很有可能就會(huì)出現(xiàn)意想不到的bug。
有人可能會(huì)說,這不是前端的問題嗎,讓前端校驗(yàn)去。話是這么說,但我們也不能前端校驗(yàn)百分百不會(huì)出現(xiàn)問題。并且有些請求可能也不是正規(guī)通過客戶端發(fā)來的,可能是黑客惡意攻擊,又或是通過Postman等發(fā)來的,這些請求就不一定會(huì)“合法”了。
因此,對(duì)客戶端傳來的每個(gè)請求都進(jìn)行必要的參數(shù)校驗(yàn)是十分重要的。而很多簡單的校驗(yàn)如果都需要程序員自己去寫的話,就會(huì)導(dǎo)致代碼過于冗長、繁瑣。為了讓校驗(yàn)更加簡潔明了,Spring為我們提供了Validation工具類來提供各種校驗(yàn)方法。
一、Validation常見的校驗(yàn)注解
空校驗(yàn)注解:
@Null
:被注釋的元素必須為null
。@NotNull
:被注釋的元素必須不為null
。@NotBlank
:被注釋的字符串去掉前后空格后長度必須非零。@NotEmpty
:被注釋的字符串、集合或數(shù)組不能為空(字符串長度非零、集合大小非零)。
布爾校驗(yàn)注解:
@AssertTrue
:被注釋的元素必須為true
。@AssertFalse
:被注釋的元素必須為false
。
日期校驗(yàn)注解:
@Past
:被注釋的元素必須是一個(gè)過去的日期。@Future
:被注釋的元素必須是一個(gè)將來的日期。
數(shù)字校驗(yàn)注解:
@Min(value)
:被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值。@Max(value)
:被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值。@DecimalMin(value)
:被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值。@DecimalMax(value)
:被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值。
長度校驗(yàn)注解:
@Size(max, min)
:被注釋的元素(如字符串、集合、數(shù)組)的大小必須在指定的范圍內(nèi)。
模式匹配校驗(yàn)注解:
@Pattern(regexp)
:被注釋的元素必須符合指定的正則表達(dá)式。
郵箱校驗(yàn)注解:
@Email
:被注釋的元素必須是電子郵箱地址。
范圍校驗(yàn)注解:
@Range(min, max)
:被注釋的元素必須在合適的范圍內(nèi)。
二、Validation的簡單應(yīng)用
首先我們需要導(dǎo)入Validation的依賴:
<!--validation依賴,負(fù)責(zé)參數(shù)校驗(yàn)--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
接著在需要使用校驗(yàn)的類上添加@Validation注解
接著主要有兩種方式使用校驗(yàn)注解:
1、直接在對(duì)應(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í)體類添加校驗(yàn)
對(duì)于一些實(shí)體類來說,直接在參數(shù)上加注解就不太可取了,程序會(huì)無法定位到指定參數(shù)。
需要再實(shí)體類內(nèi)部對(duì)應(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)建時(shí)間 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime;//更新時(shí)間 }
接著在使用實(shí)體類的地方加上 @Validated 注解,就能讓這些校驗(yàn)生效了:
@PutMapping("/update") public Result update(@RequestBody @Validated User user){ //業(yè)務(wù)邏輯 return Result.success(); }
三、分組校驗(yàn)
前面我們介紹了如何在實(shí)體類中添加校驗(yàn)注解。但是,事實(shí)上在實(shí)現(xiàn)不同功能時(shí),對(duì)同一個(gè)實(shí)體類的校驗(yàn)規(guī)則可能是會(huì)有差異的。
比如在添加用戶的場景下,用戶的id值就是在存入數(shù)據(jù)庫后生成的,在參數(shù)傳遞時(shí)自然就不是必傳項(xiàng);而在更新用戶的場景下,我們需要通過id定位指定用戶,完成信息更新操作,這時(shí)在參數(shù)傳遞時(shí)id就是必傳項(xiàng)了。
這樣,對(duì)id值的校驗(yàn)就會(huì)產(chǎn)生沖突了。如果將id設(shè)定為必傳值,那么就會(huì)導(dǎo)致添加用戶的操作可能出現(xiàn)錯(cuò)誤。不把id設(shè)定為必傳值,更新用戶的操作又會(huì)出現(xiàn)錯(cuò)誤。
為了應(yīng)對(duì)這一問題,就可以對(duì)校驗(yàn)項(xiàng)進(jìn)行分組歸類。具體操作步驟如下:
在實(shí)體類內(nèi)部定義相應(yīng)組別接口:
public class User { //各成員變量 //添加用戶類分組 public interface Add extends Default { } //更新用戶類分組 public interface Update extends Default{ } }
注意:如果沒有手動(dòng)對(duì)校驗(yàn)項(xiàng)進(jìn)行分組,其默認(rèn)就在 Default 組
對(duì)校驗(yàn)項(xiàng)進(jìn)行分組,只需要通過groups屬性指定組別即可:
@NotNull(groups = Update.class)
接著在校驗(yàn)時(shí)指定對(duì)應(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(); }
這樣就能實(shí)現(xiàn)不同業(yè)務(wù)場景下的多樣化校驗(yàn)了。
四、自定義校驗(yàn)
實(shí)際開發(fā)中的校驗(yàn)規(guī)則可能是五花八門的,但官方提供的校驗(yàn)注解就這么多,很多時(shí)候并不能滿足我們的校驗(yàn)需求。這時(shí)候就需要通過自定義校驗(yàn)注解來實(shí)現(xiàn)個(gè)性化的校驗(yàn)了。
首先需要定義一個(gè)注解:
@Documented //元注解 @Target(ElementType.FIELD) //元注解 @Retention(RetentionPolicy.RUNTIME) //元注解 @Constraint(validatedBy = {/*校驗(yàn)規(guī)則*/}) //自定義校驗(yàn)規(guī)則 public @interface State { //提供校驗(yàn)失敗后的提示信息 String message() default "state參數(shù)的值只能是已發(fā)布或草稿"; //指定分組 Class<?>[] groups() default {}; //負(fù)載 獲取到State注解的附加信息 Class<? extends Payload>[] payload() default {}; }
接著定義一個(gè)類去實(shí)現(xiàn) ConstraintValidator 接口,并實(shí)現(xiàn) isValid 方法:
public class StateValidation implements ConstraintValidator<State,String> { @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { //返回true表示校驗(yàn)通過,返回false則表示校驗(yàn)不通過 if(value==null) return false; if(value.equals("已發(fā)布")||value.equals("草稿"))return true; return false; } }
然后就要在之前定義的注解中的@Constraint中填入自定義類:
@Constraint(validatedBy = {StateValidation.class}) //自定義校驗(yàn)規(guī)則
接著就可以像使用其它校驗(yàn)注解一樣來使用自己自定義的注解了:
那么本篇文章就到此為止了,如果覺得這篇文章對(duì)你有幫助的話,可以點(diǎn)一下關(guān)注和點(diǎn)贊來支持作者哦。如果有什么講的不對(duì)的地方歡迎在評(píng)論區(qū)指出,希望能夠和你們一起進(jìn)步?
到此這篇關(guān)于spring 參數(shù)校驗(yàn)Validation的文章就介紹到這了,更多相關(guān)spring 參數(shù)校驗(yàn)Validation內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java springboot項(xiàng)目jar發(fā)布過程解析
這篇文章主要介紹了Java springboot項(xiàng)目jar發(fā)布過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09Java報(bào)錯(cuò):java.util.concurrent.ExecutionException的解決辦法
在Java并發(fā)編程中,我們經(jīng)常使用java.util.concurrent包提供的工具來管理和協(xié)調(diào)多個(gè)線程的執(zhí)行,va并發(fā)編程中,然而,在使用這些工具時(shí),可能會(huì)遇到各種各樣的異常,其中之一就是java.util.concurrent.ExecutionException,本文將詳細(xì)分析這種異常的背景、可能的原因2024-09-09java開發(fā)分布式服務(wù)框架Dubbo原理機(jī)制詳解
這篇文章主要為大家介紹了java開發(fā)分布式服務(wù)框架Dubbo的原理機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11Java實(shí)現(xiàn)將Word轉(zhuǎn)換成Html的示例代碼
在業(yè)務(wù)中,常常會(huì)需要在瀏覽器中預(yù)覽Word文檔,或者需要將Word文檔轉(zhuǎn)成HTML文件保存,本文主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)Word轉(zhuǎn)換成Html的相關(guān)方法,希望對(duì)大家有所幫助2024-02-02java基于遞歸算法實(shí)現(xiàn)漢諾塔問題實(shí)例
這篇文章主要介紹了java基于遞歸算法實(shí)現(xiàn)漢諾塔問題,結(jié)合具體實(shí)例形式分析了java遞歸算法的實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下2017-07-07創(chuàng)建好SpringBoot項(xiàng)目后但是找不到Maven的解決方法
在使用IDEA專業(yè)版創(chuàng)建好SpringBoot項(xiàng)目后,發(fā)現(xiàn)上方導(dǎo)航欄的運(yùn)行按鈕是灰色的,而且左側(cè)導(dǎo)航欄的pom.xml的圖標(biāo)顏色也不是正常的,點(diǎn)開右側(cè)導(dǎo)航欄的Maven后,發(fā)現(xiàn)Maven找不到,所以本文介紹了創(chuàng)建好SpringBoot項(xiàng)目后但是找不到Maven的解決方法,需要的朋友可以參考下2024-10-10