<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一坨一坨的 if/else 參數(shù)校驗(yàn),終于被 SpringBoot 參數(shù)校驗(yàn)組件整干凈了!

          共 4323字,需瀏覽 9分鐘

           ·

          2021-04-23 13:25

          數(shù)據(jù)的校驗(yàn)的重要性就不用說了,即使在前端對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)的情況下,我們還是要對(duì)傳入后端的數(shù)據(jù)再進(jìn)行一遍校驗(yàn),避免用戶繞過瀏覽器直接通過一些 HTTP 工具直接向后端請(qǐng)求一些違法數(shù)據(jù)。

          最普通的做法就像下面這樣。我們通過 if/else 語句對(duì)請(qǐng)求的每一個(gè)參數(shù)一一校驗(yàn)。

          這樣的代碼,小伙伴們?cè)谌粘i_發(fā)中一定不少見,很多開源項(xiàng)目都是這樣對(duì)請(qǐng)求入?yún)⒆鲂r?yàn)的。

          但是,不太建議這樣來寫,這樣的代碼明顯違背了 單一職責(zé)原則。大量的非業(yè)務(wù)代碼混雜在業(yè)務(wù)代碼中,非常難以維護(hù),還會(huì)導(dǎo)致業(yè)務(wù)層代碼冗雜!

          實(shí)際上,我們是可以通過一些簡單的手段對(duì)上面的代碼進(jìn)行改進(jìn)的!這也是本文主要要介紹的內(nèi)容!

          廢話不多說!下面我會(huì)結(jié)合自己在項(xiàng)目中的實(shí)際使用經(jīng)驗(yàn),通過實(shí)例程序演示如何在 SpringBoot 程序中優(yōu)雅地的進(jìn)行參數(shù)驗(yàn)證(普通的 Java 程序同樣適用)。

          不了解的朋友一定要好好看一下,學(xué)完馬上就可以實(shí)踐到項(xiàng)目上去。

          并且,本文示例項(xiàng)目使用的是目前最新的 Spring Boot 版本 2.4.5!(截止到 2021-04-21)

          示例項(xiàng)目源代碼地址:https://github.com/CodingDocs/springboot-guide/tree/master/source-code/bean-validation-demo

          添加相關(guān)依賴

          如果開發(fā)普通 Java 程序的的話,你需要可能需要像下面這樣依賴:

          不過,相信大家都是使用的 Spring Boot 框架來做開發(fā)。

          基于 Spring Boot 的話,就比較簡單了,只需要給項(xiàng)目添加上 spring-boot-starter-web 依賴就夠了,它的子依賴包含了我們所需要的東西。另外,我們的示例項(xiàng)目中還使用到了 Lombok。

          但是?。?!Spring Boot 2.3 1 之后,spring-boot-starter-validation 已經(jīng)不包括在了 spring-boot-starter-web 中,需要我們手動(dòng)加上!


          驗(yàn)證 Controller 的輸入

          驗(yàn)證請(qǐng)求體

          驗(yàn)證請(qǐng)求體即使驗(yàn)證被 @RequestBody 注解標(biāo)記的方法參數(shù)。

          PersonController

          我們?cè)谛枰?yàn)證的參數(shù)上加上了@Valid注解,如果驗(yàn)證失敗,它將拋出MethodArgumentNotValidException。默認(rèn)情況下,Spring 會(huì)將此異常轉(zhuǎn)換為 HTTP Status 400(錯(cuò)誤請(qǐng)求)。

          PersonRequest

          我們使用校驗(yàn)注解對(duì)請(qǐng)求的參數(shù)進(jìn)行校驗(yàn)!

          正則表達(dá)式說明:

          • ^string : 匹配以 string 開頭的字符串
          • string$ :匹配以 string 結(jié)尾的字符串
          • ^string$ :精確匹配 string 字符串
          • (^Man$|^Woman$|^UGM$) : 值只能在 Man,Woman,UGM 這三個(gè)值中選擇

          GlobalExceptionHandler

          自定義異常處理器可以幫助我們捕獲異常,并進(jìn)行一些簡單的處理。如果對(duì)于下面的處理異常的代碼不太理解的話,可以查看這篇文章 《SpringBoot 處理異常的幾種常見姿勢》。

          通過測試驗(yàn)證

          下面我通過 MockMvc 模擬請(qǐng)求 Controller 的方式來驗(yàn)證是否生效。當(dāng)然了,你也可以通過 Postman 這種工具來驗(yàn)證。

          使用 Postman 驗(yàn)證

          驗(yàn)證請(qǐng)求參數(shù)

          驗(yàn)證請(qǐng)求參數(shù)(Path Variables 和 Request Parameters)即是驗(yàn)證被 @PathVariable 以及 @RequestParam 標(biāo)記的方法參數(shù)。

          PersonController

          一定一定不要忘記在類上加上 Validated 注解了,這個(gè)參數(shù)可以告訴 Spring 去校驗(yàn)方法參數(shù)。

          ExceptionHandler

          通過測試驗(yàn)證

          使用 Postman 驗(yàn)證

          驗(yàn)證 Service 中的方法

          我們還可以驗(yàn)證任何 Spring Bean 的輸入,而不僅僅是 Controller 級(jí)別的輸入。通過使用@Validated@Valid注釋的組合即可實(shí)現(xiàn)這一需求!

          一般情況下,我們?cè)陧?xiàng)目中也更傾向于使用這種方案。

          一定一定不要忘記在類上加上 Validated 注解了,這個(gè)參數(shù)可以告訴 Spring 去校驗(yàn)方法參數(shù)。

          通過測試驗(yàn)證:

          輸出結(jié)果如下:

          name 不能為空
          sex 值不在可選范圍

          Validator 編程方式手動(dòng)進(jìn)行參數(shù)驗(yàn)證

          某些場景下可能會(huì)需要我們手動(dòng)校驗(yàn)并獲得校驗(yàn)結(jié)果。

          我們通過 Validator 工廠類獲得的 Validator 示例。另外,如果是在 Spring Bean 中的話,還可以通過 @Autowired 直接注入的方式。

          @Autowired
          Validator validate

          具體使用情況如下:

          輸出結(jié)果如下:

          sex 值不在可選范圍
          name 不能為空

          自定以 Validator(實(shí)用)

          如果自帶的校驗(yàn)注解無法滿足你的需求的話,你還可以自定義實(shí)現(xiàn)注解。

          案例一:校驗(yàn)特定字段的值是否在可選范圍

          比如我們現(xiàn)在多了這樣一個(gè)需求:PersonRequest 類多了一個(gè) Region 字段,Region 字段只能是ChinaChina-Taiwan、China-HongKong這三個(gè)中的一個(gè)。

          第一步,你需要?jiǎng)?chuàng)建一個(gè)注解 Region。

          第二步,你需要實(shí)現(xiàn) ConstraintValidator接口,并重寫isValid 方法。

          現(xiàn)在你就可以使用這個(gè)注解:

          @Region
          private String region;

          通過測試驗(yàn)證

          使用 Postman 驗(yàn)證

          案例二:校驗(yàn)電話號(hào)碼

          校驗(yàn)我們的電話號(hào)碼是否合法,這個(gè)可以通過正則表達(dá)式來做,相關(guān)的正則表達(dá)式都可以在網(wǎng)上搜到,你甚至可以搜索到針對(duì)特定運(yùn)營商電話號(hào)碼段的正則表達(dá)式。

          PhoneNumber.java

          PhoneNumberValidator.java

          搞定,我們現(xiàn)在就可以使用這個(gè)注解了。

          通過測試驗(yàn)證

          使用驗(yàn)證組

          驗(yàn)證組我們基本是不會(huì)用到的,也不太建議在項(xiàng)目中使用,理解起來比較麻煩,寫起來也比較麻煩。簡單了解即可!

          當(dāng)我們對(duì)對(duì)象操作的不同方法有不同的驗(yàn)證規(guī)則的時(shí)候才會(huì)用到驗(yàn)證組。

          我寫一個(gè)簡單的例子,你們就能看明白了!

          1.先創(chuàng)建兩個(gè)接口,代表不同的驗(yàn)證組

          public interface AddPersonGroup {
          }
          public interface DeletePersonGroup {
          }

          2.使用驗(yàn)證組

          通過測試驗(yàn)證:

          驗(yàn)證組使用下來的體驗(yàn)就是有點(diǎn)反模式的感覺,讓代碼的可維護(hù)性變差了!盡量不要使用!

          常用校驗(yàn)注解總結(jié)

          JSR303 定義了 Bean Validation(校驗(yàn))的標(biāo)準(zhǔn) validation-api,并沒有提供實(shí)現(xiàn)。Hibernate Validation是對(duì)這個(gè)規(guī)范/規(guī)范的實(shí)現(xiàn) hibernate-validator,并且增加了 @Email、@Length、@Range 等注解。Spring Validation 底層依賴的就是Hibernate Validation。

          JSR 提供的校驗(yàn)注解:

          • @Null 被注釋的元素必須為 null
          • @NotNull 被注釋的元素必須不為 null
          • @AssertTrue 被注釋的元素必須為 true
          • @AssertFalse 被注釋的元素必須為 false
          • @Min(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
          • @Max(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
          • @DecimalMin(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
          • @DecimalMax(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
          • @Size(max=, min=) 被注釋的元素的大小必須在指定的范圍內(nèi)
          • @Digits (integer, fraction) 被注釋的元素必須是一個(gè)數(shù)字,其值必須在可接受的范圍內(nèi)
          • @Past 被注釋的元素必須是一個(gè)過去的日期
          • @Future 被注釋的元素必須是一個(gè)將來的日期
          • @Pattern(regex=,flag=) 被注釋的元素必須符合指定的正則表達(dá)式

          Hibernate Validator 提供的校驗(yàn)注解

          • @NotBlank(message =) 驗(yàn)證字符串非 null,且長度必須大于 0
          • @Email 被注釋的元素必須是電子郵箱地址
          • @Length(min=,max=) 被注釋的字符串的大小必須在指定的范圍內(nèi)
          • @NotEmpty 被注釋的字符串的必須非空
          • @Range(min=,max=,message=) 被注釋的元素必須在合適的范圍內(nèi)

          拓展

          經(jīng)常有小伙伴問到:“@NotNull@Column(nullable = false) 兩者有什么區(qū)別?”

          我這里簡單回答一下:

          • @NotNull是 JSR 303 Bean 驗(yàn)證批注,它與數(shù)據(jù)庫約束本身無關(guān)。
          • @Column(nullable = false) : 是 JPA 聲明列為非空的方法。

          總結(jié)來說就是即前者用于驗(yàn)證,而后者則用于指示數(shù)據(jù)庫創(chuàng)建表的時(shí)候?qū)Ρ淼募s束。


          歡迎準(zhǔn)備面試的朋友加入我的星球,一個(gè)純 Java 面試交流圈子 !Ready!。目前星球已經(jīng)更新 3 個(gè)原創(chuàng)小冊(cè):《Java面試進(jìn)階指北》、《從零開始寫一個(gè) RPC 框架》 、《程序員副業(yè)賺錢之路》。累計(jì)幫助 520+ 位球友提供了免費(fèi)的簡歷修改服務(wù),回答了 500+ 個(gè)問題,產(chǎn)出了 1300+ 個(gè)主題。

          推薦?? :1049天,100K!簡單復(fù)盤!

          推薦?? :年薪 40W Java 開發(fā)是什么水平?

          推薦?? :Github掘金計(jì)劃:Github上的一些優(yōu)質(zhì)項(xiàng)目搜羅

          我是 Guide哥,擁抱開源,喜歡烹飪。Github 接近 10w 點(diǎn)贊的開源項(xiàng)目 JavaGuide 的作者。未來幾年,希望持續(xù)完善 JavaGuide,爭取能夠幫助更多學(xué)習(xí) Java 的小伙伴!共勉!凎!點(diǎn)擊查看我的2020年工作匯報(bào)!
          原創(chuàng)不易,歡迎點(diǎn)贊分享。咱們下期再會(huì)!
          瀏覽 130
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天日,天天插 | 内射学生妹视频在线免费观看 | 青娱乐少妇在线免费视频 | 欧美激情爱爱 | 国产人人色 |