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. 結束語:
今天的分享就到這裡啦,歡迎大家點贊、轉發、留言、拍磚~
更多內容,可以加入IT交流群565734203與大家一起討論交流
這裡是技能樹·IT修真院:https://www.jnshu.com,初學者轉行到網際網路的聚集地