項目中參數校驗,用到JSR 303,在此總結梳理下知識脈絡,拋磚引玉。 一、基礎 1.What is JSR? JSR是Java Specification Requests的縮寫,意思是Java 規範提案。任何人都可以提交JSR,以向Java平臺增添新的API和服務。JSR已成為Java界的一個重 ...
項目中參數校驗,用到JSR 303,在此總結梳理下知識脈絡,拋磚引玉。
一、基礎
1.What is JSR?
JSR是Java Specification Requests的縮寫,意思是Java 規範提案。任何人都可以提交JSR,以向Java平臺增添新的API和服務。JSR已成為Java界的一個重要標準。
2.Why use JSR 303?
問題:在通常的情況下,應用程式是分層的,不同的層由不同的開發人員來完成。很多時候同樣的數據驗證邏輯會出現在不同的層,這樣耗時且容易出錯,導致代碼冗餘和一些管理的問題。
想法:為了避免這樣的情況發生,最好是將驗證邏輯與相應的域模型進行綁定。(開發者更傾向於將驗證規則直接放到 Java Bean 本身,使用註解的方式進行驗證規則的設計。)
解決方案:Bean Validation為JavaBean 驗證定義了相應的元數據模型(註解)和 API,它是一個運行時的數據驗證框架,來使用其定義的驗證檢查JavaBean屬性值,在驗證之後驗證的錯誤信息會被馬上返回(Hibernate Validator 是 Bean Validation 的參考實現 ,提供了 JSR 303 規範中所有內置 constraint 的實現,除此之外還有一些附加的 constraint)。
3.常用
·空檢查
@NotNull 驗證對象 是否不為null, 無法查檢長度為0的字元串
@NotEmpty 檢查約束元素(String類、Collection、Map、數組)是否為NULL或者是EMPTY(實際意義等同於 @NotNull 和 @Size(min=1)的組合)
@NotBlank 檢查約束字元串 是不是Null還有被Trim的長度是否大於0,只對字元串,且會去掉前後空格
·長度檢查
@Length(max, min) Validates that the annotated 字元串 is between min and max included.
@Size(max, min) 驗證對象(Array,Collection,Map,String)長度是否在給定的範圍之內
·數字大小
@Min(value) 驗證 Number 和 String 對象是否大等於指定的值
@Max(value) 驗證 Number 和 String 對象是否小等於指定的值
@Range(min, max) 檢查數字是否介於min和max之間
@DecimalMin 驗證 Number 和 String 對象是否大等於指定的值,這個約束的參數是一個通過BigDecimal定義的最小值的字元串表示,小數存在精度
@DecimalMax 驗證 Number 和 String 對象是否小等於指定的值,這個約束的參數是一個通過BigDecimal定義的最大值的字元串表示,小數存在精度
註:上述註解具體對象為 BigDecimal,BigInteger, byte,short, int, long等任何Number或CharSequence(存儲的是數字)子類型。
·小數精度
@Digits (integer, fraction) 驗證 Number 和 String 的構成是否合法(符合指定格式的數字),integer是整數精度(整數位數上限),fraction是小數精度(小數位數上限)
4.constraint (約束)
通常由 annotation 和相應的 constraint validator 組成,它們是一對多的關係。在運行時,Bean Validation 框架本身會根據被註釋元素的類型來選擇合適的 constraint validator 對數據進行驗證。(自己也可使用內置的constraint定製化所需constraint,或者新開發constraint — 繼承ConstraintValidator)
二、高級
1.嵌套(遞歸)校驗
場景:被校驗JavaBean 包含的屬性,有的是引用類型且包含需要校驗的參數
使用方式:該屬性前面聲明@Valid,才會對屬性對象內的註解進行驗證,否則將不予驗證;如果關聯對象是個集合或者數組,那麼對其中的元素進行遞歸校驗,如果是一個map,則對其中的值部分進行校驗。
2.組
場景:對接不同項目,有些參數有時是需要的,有時又是不需要的;再比如說對於一個實體類來的id來說,保存的時候是不需要的,對於更新時是必須的
使用方式:@Validated( { First.class, Second.class }) ,@Valid(groups=GroupA.class),@NotEmpty(message = "lastname may be empty",groups = GroupA.class)
作用:無需對該對象中所有的約束進行驗證,只需要對該組定義的一個子集進行驗證即可
3.自定義constraint (約束)
4.非參數校驗的位置
其實在整個程式的任何地方都可以調用 JSR 303 API 去對數據進行校驗,然後將校驗後的結果返回:
流程:
結束語
把項目中的問題作為切入點,這次整理讓我自己受益良多:更加清楚地梳理&充實了知識框架,也瞭解到了更多工作時不一定用到的知識(可以作為本人待探索的領域)。 接下來,要解決自己一直以來的軟肋,要動手創建項目 to 實踐整理出的理論。
參考文章
1.JSR 303 - Bean Validation 介紹及最佳實踐 https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/
2.百度百科
3.Java的Validator框架概述 http://blog.csdn.net/zhu_tianwei/article/details/43272181
4.http://blog.csdn.net/wangpeng047/article/details/41726299
5.https://www.cnblogs.com/yangzhilong/p/3724967.html
6.http://jinnianshilongnian.iteye.com/blog/1733708