SpringMVC數(shù)據(jù)校驗(yàn)

使用SpringMVC時(shí)配合hibernate-validate進(jìn)行參數(shù)的合法性校驗(yàn),驗(yàn)證客戶輸入的數(shù)據(jù)是否合法捆昏,能節(jié)省一定的代碼量赚楚。

1. 搭建Web工程并引入hibernate-validate依賴

  <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.1.2.Final</version>
  </dependency>
  <dependency>
     <groupId>org.glassfish</groupId>
     <artifactId>jakarta.el</artifactId>
     <version>3.0.3</version>
  </dependency>
  <dependency>
     <groupId>org.hibernate.validator</groupId>
     <artifactId>hibernate-validator-cdi</artifactId>
     <version>6.1.2.Final</version>
  </dependency>

2. SpringMVC.xml配置

    <!-- 將校驗(yàn)器交給適配器 -->
    <mvc:annotation-driven validator="validator"></mvc:annotation-driven>
    <!-- 配置校驗(yàn)器 -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <!-- 提供校驗(yàn)的類 -->
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
        <!-- 可以配置國際化錯(cuò)誤信息保存的文件,也可在校驗(yàn)注解使用message屬性進(jìn)行配置但會(huì)失去國際化的功能 -->
        <property name="validationMessageSource" ref="messageSource"></property>
    </bean>
<!-- 讀取外部配置文件 -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!-- 文件路徑 -->
        <property name="basenames">
            <array>
                <value>classpath:CustomValidationMessages</value>
            </array>
        </property>
        <!-- 設(shè)置編碼格式 -->
        <property name="defaultEncoding" value="utf-8"></property>
        <!-- 文件緩存的時(shí)間 :以秒為單位 -->
        <property name="cacheSeconds" value="60"></property>
    </bean>

自定義校驗(yàn)信息提示文件CustomValidationMessages.properties

emp.empno=\u96C7\u5458\u7F16\u53F7\u53EA\u80FD\u4E3A\u56DB\u4F4D\u6570\u5B57\u7EC4\u6210  //雇員編號(hào)只能為四位數(shù)字組成
emp.ename=\u96C7\u5458\u59D3\u540D\u53EA\u80FD\u7531\u6570\u5B57\u3001\u5B57\u6BCD\u3001\u4E0B\u5212\u7EBF\u3001\u957F\u77ED\u5FC5\u987B\u57286-10\u4F4D\u4E4B\u95F4  //雇員編號(hào)只能為四位數(shù)字組成
emp.job=\u804C\u4F4D\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A  //職位名稱不能為空
emp.email=\u975E\u6CD5\u90AE\u7BB1 //非法郵箱

3. 使用校驗(yàn)注解標(biāo)注在屬性上(DTO)



*每個(gè)注解都有message屬性骗卜,該屬性用于填寫校驗(yàn)失敗時(shí)的異常描述信息宠页,當(dāng)校驗(yàn)失敗時(shí)可以獲取對(duì)應(yīng)的message屬性值。

4. Spring MVC 數(shù)據(jù)校驗(yàn)

  • Spring 4.0 擁有自己獨(dú)立的數(shù)據(jù)校驗(yàn)框架寇仓,同時(shí)支持 JSR 303 標(biāo)準(zhǔn)的校驗(yàn)框架举户。
  • Spring 在進(jìn)行數(shù)據(jù)綁定時(shí),可同時(shí)調(diào)用校驗(yàn)框架完成數(shù)據(jù)校驗(yàn)工作遍烦。在 Spring MVC 中俭嘁,可直接通過注解驅(qū)動(dòng)的方式進(jìn)行數(shù)據(jù)校驗(yàn)
  • Spring 的 LocalValidatorFactroyBean 既實(shí)現(xiàn)了 Spring 的 Validator 接口,也實(shí)現(xiàn)了 JSR 303 的 Validator 接口服猪。只要在 Spring 容器中定義了一個(gè) LocalValidatorFactoryBean供填,即可將其注入到需要數(shù)據(jù)校驗(yàn)的 Bean 中拐云。
  • Spring 本身并沒有提供 JSR303 的實(shí)現(xiàn),所以必須將 JSR303 的實(shí)現(xiàn)者的 jar 包放到類路徑下近她。

  • <mvc:annotation-driven/> 會(huì)默認(rèn)裝配好一個(gè) LocalValidatorFactoryBean慨丐,通過在處理方法的入?yún)⑸蠘?biāo)注 @valid 注解即可讓 Spring MVC 在完成數(shù)據(jù)綁定后執(zhí)行數(shù)據(jù)校驗(yàn)的工作
  • Spring MVC 是通過對(duì)處理方法簽名的規(guī)約來保存校驗(yàn)結(jié)果的:前一個(gè)表單/命令對(duì)象的校驗(yàn)結(jié)果保存到隨后的入?yún)⒅校@個(gè)保存校驗(yàn)結(jié)果的入?yún)⒈仨毷?BindingResult 或 Errors 類型泄私,這兩個(gè)類都位于 org.springframework.validation 包中

  • 需校驗(yàn)的 Bean 對(duì)象和其綁定結(jié)果對(duì)象或錯(cuò)誤對(duì)象時(shí)成對(duì)出現(xiàn)的,它們之間不允許聲明其他的入?yún)?/strong>
  • Errors 接口提供了獲取錯(cuò)誤信息的方法备闲,如 getErrorCount() 或 getFieldErrors(String field)
  • BindingResult 擴(kuò)展了 Errors 接口


    image.png

5. 使用@Validated/@Valid注解開啟對(duì)參數(shù)的校驗(yàn)

  • @Validated注解表示開啟Spring的校驗(yàn)機(jī)制晌端,支持分組校驗(yàn),聲明在入?yún)⑸稀?/li>
  • @Valid注解表示開啟Hibernate的校驗(yàn)機(jī)制,不支持分組校驗(yàn),聲明在入?yún)⑸稀?/li>
  • 在DTO后面緊跟BindingResult對(duì)象恬砂,那么當(dāng)參數(shù)不符合時(shí)咧纠,能通過該對(duì)象直接獲取不符合校驗(yàn)的message描述信息。
  • 若使用了@Validated/@Valid注解開啟校驗(yàn)泻骤,但DTO后面沒有緊跟BindingResult對(duì)象漆羔,那么當(dāng)參數(shù)不符合時(shí),將直接返回400 Bad Request狀態(tài)碼狱掂。

6. 在頁面上顯示錯(cuò)誤(需要引入SpringMVC表單標(biāo)簽庫)

  • Spring MVC 除了會(huì)將表單/命令對(duì)象的校驗(yàn)結(jié)果保存到對(duì)應(yīng)的 BindingResult 或 Errors 對(duì)象中外演痒,還會(huì)將所有校驗(yàn)結(jié)果保存到 “隱含模型”
  • 即使處理方法的簽名中沒有對(duì)應(yīng)于表單/命令對(duì)象的結(jié)果入?yún)ⅲr?yàn)結(jié)果也會(huì)保存在 “隱含對(duì)象” 中趋惨。
  • 隱含模型中的所有數(shù)據(jù)最終將通過 HttpServletRequest 的屬性列表暴露給 JSP 視圖對(duì)象鸟顺,因此在 JSP 中可以獲取錯(cuò)誤信息
  • 在 JSP 頁面上可通過 <form:errors path=“userName”> 顯示錯(cuò)誤消息

7. 示例

public class Emp {
    @Max(value = 9999L)
    @Min(value = 1000)
    private int empno;

    @Pattern(regexp = "[0-9A-Za-z_]{6,10}", message = "雇員姓名只能由數(shù)字、字母器虾、下劃線讯嫂、長短必須在6-10位之間")
    private String ename;

    @NotBlank(message = "工作不能為空")
    private String job;

    private int mgr;

    private Date hiredate;

    @Email(message = "非法郵箱!")
    private String email;

    private double sal;

    private double comm;

    private Dept dept;

    ...
    @RequestMapping("/adduser")
    public void addUser(@Validated Emp emp, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<ObjectError> errors = bindingResult.getAllErrors();
            for (ObjectError objectError : errors) {
                System.out.println(objectError.getDefaultMessage());
            }
        }
        System.out.println(emp.getHiredate());
    }

8. 提示消息的國際化

上述例子代碼中,我們自定義錯(cuò)誤消息兆沙,使用了message 屬性來自定義消息描述欧芽,但是這樣做我們就失去了國際化的功能,消息國際化我們可以通過編寫國際化配置文件來實(shí)現(xiàn)

當(dāng)使用 Spring MVC 標(biāo)簽顯示錯(cuò)誤消息時(shí)葛圃, Spring MVC 會(huì)查看 WEB 上下文是否裝配了對(duì)應(yīng)的國際化消息千扔,如果沒有,則顯示默認(rèn)的錯(cuò)誤消息装悲,否則使用國際化消息昏鹃。

配置校驗(yàn)器以及國際化配置文件

    <!-- 將校驗(yàn)器交給適配器 -->
    <mvc:annotation-driven validator="validator"></mvc:annotation-driven>
    <!-- 配置校驗(yàn)器 -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <!-- 提供校驗(yàn)的類 -->
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
        <!-- 可以配置國際化錯(cuò)誤信息保存的文件,也可在校驗(yàn)注解使用message屬性進(jìn)行配置但會(huì)失去國際化的功能 -->
        <property name="validationMessageSource" ref="messageSource"></property>
    </bean>
<!-- 讀取外部配置文件 -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!-- 文件路徑 -->
        <property name="basenames">
            <array>
                <value>classpath:CustomValidationMessages</value>
            </array>
        </property>
        <!-- 設(shè)置編碼格式 -->
        <property name="defaultEncoding" value="utf-8"></property>
        <!-- 文件緩存的時(shí)間 :以秒為單位 -->
        <property name="cacheSeconds" value="60"></property>
    </bean>

自定義校驗(yàn)信息提示文件CustomValidationMessages.properties

emp.empno=\u96C7\u5458\u7F16\u53F7\u53EA\u80FD\u4E3A\u56DB\u4F4D\u6570\u5B57\u7EC4\u6210  //雇員編號(hào)只能為四位數(shù)字組成
emp.ename=\u96C7\u5458\u59D3\u540D\u53EA\u80FD\u7531\u6570\u5B57\u3001\u5B57\u6BCD\u3001\u4E0B\u5212\u7EBF\u3001\u957F\u77ED\u5FC5\u987B\u57286-10\u4F4D\u4E4B\u95F4  //雇員編號(hào)只能為四位數(shù)字組成
emp.job=\u804C\u4F4D\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A  //職位名稱不能為空
emp.email=\u975E\u6CD5\u90AE\u7BB1 //非法郵箱

校驗(yàn)?zāi)繕?biāo)類

public class Emp {
    @Max(value = 9999L)
    @Min(value = 1000)
    private int empno;
    @Pattern(regexp = "[0-9A-Za-z_]{6,10}", message = "{emp.ename}")
    private String ename;
    @NotBlank(message = "{emp.job}")
    private String job;
    private int mgr;
    private Date hiredate;
    @Email(message = "{emp.email}")
    private String email;
    private double sal;
    private double comm;
    private Dept dept;// 一對(duì)一
    ...

9.分組校驗(yàn)

9.1. 什么是分組校驗(yàn)诀诊?

校驗(yàn)規(guī)則是在pojo 制定的洞渤,而同一個(gè)pojo可以被多個(gè)Controller使用,此時(shí)會(huì)有問題属瓣,即:不同的Controller方法對(duì)同一個(gè)pojo進(jìn)行校驗(yàn)载迄,此時(shí)這些校驗(yàn)信息是共享在這不同的Controller方法中讯柔,但是實(shí)際上每個(gè)Controller方法可能需要不同的校驗(yàn),在這種情況下护昧,就需要使用分組校驗(yàn)來解決這種問題魂迄。
通俗的講,一個(gè)pojo中有很多屬性惋耙,controller中的方法1可能只需要校驗(yàn)pojo中的屬性1捣炬,controller中的方法2只需要校驗(yàn)pojo中的屬性2,但是pojo中的校驗(yàn)注解有很多绽榛,怎樣才能使方法1只校驗(yàn)屬性1湿酸,方法二只校驗(yàn)屬性2呢?就需要用分組校驗(yàn)來解決了灭美。

9.2. 定義分組

定義分組

就是定義空的接口推溃,接口類只作為這個(gè)分組標(biāo)識(shí)來使用,看下面的用法届腐,就知道其意義何在了

9.3. 使用分組

image.png

9.4. controller方法

在這個(gè)方法中铁坎,那么就只會(huì)校驗(yàn)Emp這個(gè)pojo中有Group1.class這個(gè)分組的校驗(yàn)注解,而不會(huì)在校驗(yàn)其他的


image.png

10 擴(kuò)展知識(shí)

使用SpringMVC表單標(biāo)簽庫來參數(shù)校驗(yàn)https://www.cnblogs.com/hemou/p/12356175.html
SpringMVC表單標(biāo)簽庫http://www.reibang.com/p/b1f2d50b671c
SpringMVC_數(shù)據(jù)校驗(yàn)https://blog.csdn.net/qq_40794973/article/details/97967016

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末犁苏,一起剝皮案震驚了整個(gè)濱河市硬萍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌围详,老刑警劉巖襟铭,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異短曾,居然都是意外死亡寒砖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門嫉拐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哩都,“玉大人,你說我怎么就攤上這事婉徘∧叮” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵盖呼,是天一觀的道長儒鹿。 經(jīng)常有香客問我,道長几晤,這世上最難降的妖魔是什么约炎? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上圾浅,老公的妹妹穿的比我還像新娘掠手。我一直安慰自己,他們只是感情好狸捕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布喷鸽。 她就那樣靜靜地躺著,像睡著了一般灸拍。 火紅的嫁衣襯著肌膚如雪做祝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天鸡岗,我揣著相機(jī)與錄音剖淀,去河邊找鬼。 笑死纤房,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的翻诉。 我是一名探鬼主播炮姨,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼碰煌!你這毒婦竟也來了舒岸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤芦圾,失蹤者是張志新(化名)和其女友劉穎蛾派,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體个少,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洪乍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夜焦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壳澳。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茫经,靈堂內(nèi)的尸體忽然破棺而出巷波,到底是詐尸還是另有隱情,我是刑警寧澤卸伞,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布抹镊,位于F島的核電站,受9級(jí)特大地震影響荤傲,放射性物質(zhì)發(fā)生泄漏垮耳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一遂黍、第九天 我趴在偏房一處隱蔽的房頂上張望氨菇。 院中可真熱鬧儡炼,春花似錦、人聲如沸查蓉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豌研。三九已至妹田,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鹃共,已是汗流浹背鬼佣。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霜浴,地道東北人晶衷。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像阴孟,于是被迫代替她去往敵國和親晌纫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容