1. 程式人生 > >Validation 引數校驗

Validation 引數校驗

這裡是修真院後端小課堂,每篇分享文從

【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】

八個方面深度解析後端知識/技能,本篇分享的是:

Validation 引數校驗

【修真院java 小課堂】 Validation 引數校驗

 

大家好,我是IT修真院鄭州分院第12期的學員張泉良,一枚正直純潔善良的JAVA程式設計師,今天給大家分享一下,

修真院官網JAVA任務二,深度思考中的知識點——Validation 引數校驗

 

1. 背景介紹:

 

    引數驗證是一個常見的問題,無論是前端還是後臺,都需對使用者輸入進行驗證,以此來保證系統資料的正確性。

    對於web來說,有些人可能理所當然的想在前端驗證就行了,但這樣是非常錯誤的做法,前端程式碼對於使用者來說是透明的,

    稍微有點技術的人就可以繞過這個驗證,直接提交資料到後臺。引數驗證隨處可見,也是必不可少的。

    前端做驗證只是為了使用者體驗,後端才是最終的保障。

 

2. 知識剖析:

   

   (1) 常見的引數檢驗方式:

    a、表現層驗證:SpringMVC提供對JSR-303的表現層驗證,或者直接將拿到的引數在controller層裡面用if判斷

    b、業務邏輯層驗證:Spring3.1提供對業務邏輯層的方法驗證

    c、DAO層驗證:Hibernate提供DAO層的模型資料的驗證

    d、資料庫端的驗證:通過資料庫約束來進行 

 

    原理都是基於javax validation,有特殊需求的話,可以自定義校驗

 

   (2) JSR 303

    JSR 303(Java Specification Requests 規範提案)是JAVA EE 6中的一項子規範,

    一套JavaBean引數校驗的標準,叫做Bean Validation。

    JSR 303用於對Java Bean中的欄位的值進行驗證,Spring MVC 3.x之後之中也大力支援 JSR303

 

    JSR303提供的校驗註解---------可以註解在javabean的field和properties上,也可以註解在map、list上,註解很靈活

    @Null 被註釋的元素必須為 null

    @NotNull 被註釋的元素必須不為 null

    @AssertTrue 被註釋的元素必須為 true

    @AssertFalse 被註釋的元素必須為 false 

    @Min(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 

    @Max(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值

    @DecimalMin(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值

    @DecimalMax(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值

    @Size(max=, min=) 被註釋的元素的大小必須在指定的範圍內

    @Digits (integer, fraction) 被註釋的元素必須是一個數字,其值必須在可接受的範圍內

    @Past 被註釋的元素必須是一個過去的日期 

    @Future 被註釋的元素必須是一個將來的日期

    @Pattern(regex=,flag=) 被註釋的元素必須符合指定的正則表示式

    

    (3) Hibernate Validator

    Hibernate Validator是JSR-303的一個參考實現,它除了支援所有標準的校驗註解外,還支援如下擴充套件註解

    @Email 被註解的元素必須是電子郵箱地址

    @Length(min=,max=) 被註解的字串的大小必須在指定的範圍內

    @NotBlank 驗證字串非null,且長度必須大於0

    @NotEmpty 被註釋的字串的必須非空 

    @Range(min=,max=)  被註解的元素必須在合適的範圍內

 

    (4) Spring校驗框架

    Spring的org.springframework.validation是校驗框架所在的包。LocalValidatorFactoryBean既實現了

    Spring的Validator介面,又實現了JSR-303的Validator介面。只要在Spring容器中定義一個LocalValidatorFactoryBean

    即可將其注入需要資料校驗的Bean中。

 

3. 常見問題:

 

    (1) SpringValidation和javax validation的區別

    JSR303是一項標準,他們規定一些校驗規範即校驗註解,位於javax.validation.constraints包下,.只提供規範不提供實現

    Hibernate validation,他提供了相應的實現,並增加了一些其他校驗註解

    spring validation其在springmvc模組中添加了自動校驗,並將校驗資訊封裝進了特定的類中

 

    (2) 引數校驗的基本使用

    多個屬性的校驗

    在日誌或者控制檯輸出校驗的資訊

    部分註解僅能用於部分資料型別

    如@notblank註解僅用於字串,使用時需注意

 

    (3) 自定義訊息錯誤訊息

    Spring中定義了一個MessageSource介面,以用於支援資訊的國際化和包含引數的資訊的替換。

    ApplicationContext介面繼承了MessageSource介面,

    所以所有的ApplicationContext實現類都實現了MessageSource介面。

    也就是我們我們可以通過ApplicationContext來呼叫MessageSource介面方法以實現資訊的國際化和替換資訊中包含的參      數。

    

<mvc:annotation-driven validator="validator" />

<bean id="validator"     class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" >

   <property name="providerClass" value="org.hibernate.validator.HibernateValidator" />

   <!-- 如果不加預設到 使用classpath下的 ValidationMessages.properties -->

   <property name="validationMessageSource" ref="messageSource" />

</bean>

 

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

   <property name="basenames" value="classpath:messages" />

   <property name="defaultEncoding" value="UTF-8"/>

   <property name="cacheSeconds" value="60"/>

</bean>

 

4. 編碼實戰:

 

5. 拓展思考:

 

    (1)分組校驗

    分組簡單說: 解決實體中每個屬性都是設定了引數檢驗,但是在某個方法內只想檢驗部分屬性任務,也可以叫分類,

    採用介面的方式來標識,可以類比java集合中的序列化介面 (Serializable)

 

     比如說有 使用者名稱,密碼,手機號,郵箱,年齡,性別,我想要檢驗其中的任意2個屬性(假設為手機號,年齡),

      當然可以直接加入對應的註解,如果換成手機號和密碼,肯定又要寫2個註解,

     當欄位過多,並且使用場景頻繁時,分組是個不錯的選擇

 

     假設有2個分組 interface Group1,interface Group2 

     @NotNull(message = "姓名不能為空",groups = {Group1.class})

     private String name;

     指定分組後,使用@Validated(Group1.class) Student student,只檢驗指定分組

 

    (2)自定義校驗

  

         這個不建議進行,現有的檢驗型別基本夠,如果有更多要求,建議使用邏輯判斷,這樣更清晰,記錄日誌方便,出現問題可以及時排查。

 

6. 參考文獻:

 

https://blog.csdn.net/xu1916659422/article/details/77430924

https://blog.csdn.net/u013815546/article/details/77248003

 

7.  更多討論:

 

Q1:表單提交時,不填該表的內容,正常submit,預設為空字串 "",怎麼解決

 

A1:在前端驗證是否為空,後端使用isEmpty方法或者@NotEmpty註解

 

Q2: 為什麼會出現 HV000030: No validator could be found for type: java.lang.Integer.

 

A2: 可能在Integer屬性上加了不屬於整型的校驗,比如@NotEmpty,@Length等

 

Q3:數值性引數: 當輸入為空時,字串"",解析失敗之後不能再進行其他判斷,會出現NPE

 

A3:可以考慮使用自定義異常,使用Spring Aop功能攔截異常,給出自定義的錯誤資訊

 

8.  鳴謝:

 

9.  結束語:

 

今天的分享就到這裡啦,歡迎大家點贊、轉發、留言、拍磚~

 

 

PPT連結 視訊連結

更多內容,可以加入IT交流群565734203與大家一起討論交流

這裡是技能樹·IT修真院:https://www.jnshu.com,初學者轉行到網際網路的聚集地