<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
下面我們以新增一個員工為功能切入點,以常規寫法為背景,慢慢烘托出 @Valid 和 @Validated 註解用法詳解。
那麼,首先,我們會有一個員工物件 Employee,如下 :
/** * 員工物件 * * @author sunnyzyq * @since 2019/12/13 */ public class Employee { /** 姓名 */ public String name; /** 年齡 */ public Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
然後 Cotroller 中會有一個對應都新增方法 add(),如下:
@Controller public class TestController { @RequestMapping("/add") @ResponseBody public String add(Employee employee) { // TODO 儲存到資料庫 return "新增員工成功"; } }
現在要求:員工的名稱不能為空,且長度不能超過10個字元,那麼我們以前的做法大致如下:
寫完,我們啟動專案測試下:
(1)名稱為空情況
(2)正常情況
(3)超過長度情況
可以看到,和我們料想中的一樣,毫無問題。
除了名稱外,我們規定年齡也是必填項,且範圍在1到100歲,那麼此時,我們需要增加對應判定程式碼如下:
那麼問題來了,現在員工物件 Employee 就 2 個欄位,我們就寫了 10 多行的程式碼驗證,要是有20個欄位,豈不是要寫 100 多行程式碼?通常來說,當一個方法中的無效業務程式碼量過多時,往往程式碼設計有問題,當然這不是我們所想看到都結果。
那麼如何解決呢?首先大家應該會想到將對應的驗證過程抽成一個驗證方法,如下:
這樣來看,我們的業務方法就清爽多了。
但這種方式只是抽了一個方法,有一種換湯不換藥的感覺,雖然業務方法看起來清爽了很多,但書寫程式碼量並沒有下降,反而還多出了一個方法,這也不是我們理想中的樣子。
此時,我們引出 Spring 中的 @valid 註解,這些問題就可以迎刃而解了,具體如下:
首先,我們在 Maven 設定中引入 @valid 的依賴:
如果你是 springboot 專案,那麼可以不用引入了,已經引入了,他就存在於最核心的 web 開發包裡面。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.5.RELEASE</version> </dependency>
如果你不是 springboot 專案,那麼引入下面依賴即可:
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency>
那麼針對上面情景,我們可以對我們的程式碼進行優化了。
首先我們在 Employee 類的屬性上打上如下註解:
package com.zyq.beans; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; /** * 員工物件 * * @author sunnyzyq * @since 2019/12/13 */ public class Employee { /** 姓名 */ @NotBlank(message = "請輸入名稱") @Length(message = "名稱不能超過個 {max} 字元", max = 10) public String name; /** 年齡 */ @NotNull(message = "請輸入年齡") @Range(message = "年齡範圍為 {min} 到 {max} 之間", min = 1, max = 100) public Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
然後再 Controller 對應方法上,對這個員工標上 @Valid 註解,表示我們對這個物件屬性需要進行驗證,
既然驗證,那麼就肯定會有驗證結果,所以我們需要用一個東西來存放驗證結果,做法也很簡單,在引數直接新增一個BindingResult,具體如下:
對應獲取驗證結果的程式碼如下:
OK ! 萬事俱備 !我們進行測試下:
(1)名稱為空
(2)名稱正常,年齡為空
(3)名稱超出範圍,年齡正常
(4)名稱正常,年齡超出範圍
可以看到,程式碼不但簡潔了很多,結果和預期的也一模一樣!很棒吧!!
常用註解:
除了剛剛都註解,最後再附加2個常用註解,我就直接貼圖了,基本上這6個註解可以解決99%的欄位,其他註解我就不貼圖了,如果不滿足,自己問百度。
上面,我們講述了 @Valid 註解,現在我們來說說 @Validated 這個註解,在我看來,@Validated 是在 @Valid 基礎上,做的一個升級版。
我們可以看到,我們在使用 @Valid 進行驗證的時候,我們需要用一個物件去接收校驗結果,最後根據校驗結果判斷,從而提示使用者。
如果我們把手動校驗的這段程式碼刪除或註釋掉,那麼即使當我們的欄位不滿足規則時,方法種的程式也是能夠被執行的。
比如,我們將欄位值置空時,正常情況是會進行提示的。
當我們把校驗邏輯註釋掉後,再次執行上面的請求後。
可以看到我們的程式繼續往後面去執行完成了。
現在,我們去掉方法引數上的 @Valid 註解和其配對的 BindingResult 物件,
然後再校驗的物件前面新增上 @Validated 註解。
這個時候,我們再次請求,可以看到,我們請求報400錯誤了。
而我們通過程式的異常紀錄檔來看,提示說是 age 和 name 欄位為了空,致使請求失敗。
那麼,從這裡我們可以得知,當我們的資料存在校驗不通過的時候,程式就會丟擲
org.springframework.validation.BindException 的異常。
在實際開發的過程中,我們肯定不能講異常直接展示給使用者,而是給能看懂的提示。
於是,我們不妨可以通過捕獲異常的方式,將該異常進行捕獲。
首先我們建立一個校驗異常捕獲類 ValidExceptionHandler ,然後打上 @RestControllerAdvice 註解,該註解表示他會去抓所有 @Controller 標記類的異常,並在例外處理後返回以 JSON 或字串的格式響應前端。
算了,我直接將這段程式碼貼出來吧。
在異常捕捉到後,我們同上面的 @valid 校驗一樣,只返回第一個錯誤提示。
package com.zyq.config; import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class ValidExceptionHandler { @ExceptionHandler(BindException.class) public String validExceptionHandler(BindException exception) { return exception.getAllErrors().get(0).getDefaultMessage(); } }
那麼,我們現在重啟程式,然後重新請求,就可以發現介面已經不報400錯誤了,而是直接提示了我們的錯誤資訊。
最後我們來對 @Valid 和 @Validated 兩個註解進行總結下:
(1)@Valid 和 @Validated 兩者都可以對資料進行校驗,待校驗欄位上打的規則註解(@NotNull, @NotEmpty等)都可以對 @Valid 和 @Validated 生效;
(2)@Valid 進行校驗的時候,需要用 BindingResult 來做一個校驗結果接收。當校驗不通過的時候,如果手動不 return ,則並不會阻止程式的執行;
(3)@Validated 進行校驗的時候,當校驗不通過的時候,程式會丟擲400異常,阻止方法中的程式碼執行,這時需要再寫一個全域性校驗異常捕獲處理類,然後返回校驗提示。
(4)總體來說,@Validated 使用起來要比 @Valid 方便一些,它可以幫我們節省一定的程式碼,並且使得方法看上去更加的簡潔。
到此這篇關於詳解Spring中@Valid和@Validated註解用法的文章就介紹到這了,更多相關Spring @Valid @Validated內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45