SpringMVC數據校驗採用JSR-303校驗。html
• Spring 4.0 擁有本身獨立的數據校驗框架,同時支持 JSR
303 標準的校驗框架。
• Spring 在進行數據綁定時,可同時調用校驗框架完成數據校
驗工做。在 Spring MVC 中,可直接經過註解驅動的方式
進行數據校驗
• Spring 的 LocalValidatorFactroyBean 既實現了 Spring 的
Validator 接口,也實現了 JSR 303 的 Validator 接口。只要
在 Spring 容器中定義了一個
LocalValidatorFactoryBean,便可將其注入到須要數據校
驗的 Bean 中。
• Spring 自己並無提供 JSR303 的實現,因此必須將
JSR303 的實現者的 jar 包放到類路徑下java
Hibernate Validator 是 JSR 303 的一個參考實現,這裏咱們就採用Hibernate validator。git
JSR-303校驗說明:web
1.@NotNull/@Null
驗證字段: 引用數據類型
註解說明:註解元素必須是非空或空
2.@Digits
驗證字段:byte、short、int、long及各自的包裝類型以及BigDecimal、BigInteger、String
註解說明:驗證數字構成是否合法
屬性說明:integer:指定整數部分數字位數,fraction:指定小數部分數字位數
3.@Future/Past
驗證字段:java.util.Date,java.util.Calendar
註解說明:驗證是否在當前系統時間以後/以前
4.@Max/@Min
驗證字段:byte、short、int、long及對應的包裝類型以及BigDecimal、BigInteger
註解說明:驗證值是否小於等於最大指定整數值或大於等於最小指定整數值
5.@Pattern
驗證字段:String
註解說明:驗證字符串是否匹配指定的正則表達式
屬性說明:regexp:匹配的正則表達式,flags:指定Pattern.Flag的數值,表示正則表達式的選項
6.@Size
驗證字段:String、Collection、Map和數組
註解說明:驗證元素大小是否在指定範圍內
屬性說明:max:最大長度,min:最小長度,message:提示信息,默認:{constraint.size}
7.@DecimalMax/@DecimalMin
驗證字段:byte、short、int、long及對應的包裝類型以及BigDecimal、BigInteger、String
屬性說明:驗證值是否小於等於最大指定小數值或大於等於最小指定小數值
8.@Valid
屬性說明:驗證值是否須要遞歸調用正則表達式
Hibernate Validator增長了一些校驗規則:spring
1.@Email 被註釋的元素必須是電子郵箱地址
2.@Length 被註釋的字符串的大小必須在指定的範圍內
3.@NotEmpty 被註釋的字符串的必須非空
4.@Range 被註釋的元素必須在合適的範圍內
數組
使用Maven導入jar包:mvc
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.4.Final</version> </dependency>
JavaBean:app
public class Student implements Serializable { @DecimalMin("10") private Long sid; @NotNull @Pattern(regexp = "b.*") private String name; @Past @JsonSerialize(using = CustomDateSerializer.class) private Date birthday; public Long getSid() { return sid; } public void setSid(Long sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
爲了在校驗和數據轉換失敗時輸出咱們自定義的錯誤信息,咱們須要配置國際化資源文件:框架
i18n.properties:
#校驗註解名.類名全小寫.類中的屬性=xxxxx 表示進行JSR-303註解校驗失敗時使用的國際化信息 DecimalMin.student.sid=ID必須大於10喔^-^ NotNull.student.name=名字不能爲空喔 Pattern.student.name=名字必須以b開頭喔 Past.student.birthday=親,您是穿越了嘛! #[typeMismatch|required|methodInvocation].類名全小寫.類中屬性=xxxxx 表示在類型轉換失敗時使用的國際化信息 typeMismatch.student.birthday=您輸入的是一個日期嘛,親!
配置SpringMVC,
<!--註冊國際化資源文件--> <bean id = "messageSource" class = "org.springframework.context.support.ResourceBundleMessageSource"> <property name = "basename" value = "i18n" /> <property name = "defaultEncoding" value="GBK"/> </bean>
測試方法以下:
@RequestMapping("testvalid") public String TestValid( @Valid//若是須要校驗則須要駕駛@Valid註解 @ModelAttribute("student") Student student, Errors errors, Map<String, Object> map) { System.out.println(student); if (errors.hasErrors()) { System.out.println("這裏有一些錯誤"); for (FieldError fieldError : errors.getFieldErrors()) { System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage()); } return "forward:/input.jsp"; } map.put("msg", "轉換並校驗成功了!"); return "success"; }
Jsp文件以下:
<!DOCTYPE html> <html lang = "en"> <head> <base href = "<%=basePath %>" /> <meta charset = "UTF-8"> <title></title> </head> <style> span { color: red; } </style> <body> <form:errors path = "student.*" /> <form action = "hello/testvalid.do" method = "post"> ID:<input type = "text" name = "sid" value = "${student.sid}" /> <form:errors path = "student.sid" /> <br /> Name:<input type = "text" name = "name" value = "${student.name}" /> <form:errors path = "student.name" /> <br /> Birthday:<input type = "text" name = "birthday" value = "<fmt:formatDate value="${student.birthday}" pattern="yyyy-MM-dd"/>" /> <form:errors path = "student.birthday" /> <br /> <input type = "submit" value = "Commit" /> </form> </body> </html>
測試結果以下:
• <mvc:annotation-driven/> 會默認裝配好一個
LocalValidatorFactoryBean,經過在處理方法的入參上標
注 @valid 註解便可讓 Spring MVC 在完成數據綁定後執行
數據校驗的工做
• 在已經標註了 JSR303 註解的表單/命令對象前標註一個
@Valid,Spring MVC 框架在將請求參數綁定到該入參對象
後,就會調用校驗框架根據註解聲明的校驗規則實施校驗
• Spring MVC 是經過對處理方法簽名的規約來保存校驗結果
的:前一個表單/命令對象的校驗結果保存到隨後的入參
中,這個保存校驗結果的入參必須是 BindingResult 或
Errors 類型,這兩個類都位於
org.springframework.validation 包中
• 需校驗的 Bean 對象和其綁定結果對象或錯誤對象時成對出現的,它們
之間不容許聲明其餘的入參
• Errors 接口提供了獲取錯誤信息的方法,如 getErrorCount() 或
getFieldErrors(String field)
• BindingResult 擴展了 Errors 接口
• 在表單/命令對象類的屬性中標註校驗註解,在處理方法對
應的入參前添加 @Valid,Spring MVC 就會實施校驗並將校
驗結果保存在被校驗入參對象以後的 BindingResult 或
Errors 入參中。
• 經常使用方法:
– FieldError getFieldError(String field)
– List<FieldError> getFieldErrors()
– Object getFieldValue(String field)
– Int getErrorCount()
• Spring MVC 除了會將表單/命令對象的校驗結果保存到對
應的 BindingResult 或 Errors 對象中外,還會將全部校驗
結果保存到 「隱含模型」
• 即便處理方法的簽名中沒有對應於表單/命令對象的結果
入參,校驗結果也會保存在 「隱含對象」 中。
• 隱含模型中的全部數據最終將經過 HttpServletRequest 的
屬性列表暴露給 JSP 視圖對象,所以在 JSP 中能夠獲取
錯誤信息
• 在 JSP 頁面上可經過 <form:errors path=「userName」>
顯示錯誤消息
• 每一個屬性在數據綁定和數據校驗發生錯誤時,都會生成一
個對應的 FieldError 對象。
• 當一個屬性校驗失敗後,校驗框架會爲該屬性生成 4 個消
息代碼,這些代碼以校驗註解類名爲前綴,結合
modleAttribute、屬性名及屬性類型名生成多個對應的消
息代碼:例如 User 類中的 password 屬性標準了一個 @Pattern 注
解,當該屬性值不知足 @Pattern 所定義的規則時, 就會產生如下 4
個錯誤代碼:
– Pattern.user.password
– Pattern.password
– Pattern.java.lang.String
– Pattern
• 當使用 Spring MVC 標籤顯示錯誤消息時, Spring MVC 會查看
WEB 上下文是否裝配了對應的國際化消息,若是沒有,則顯示默認
的錯誤消息,不然使用國際化消息。
• 若數據類型轉換或數據格式轉換時發生錯誤,或該有的參
數不存在,或調用處理方法時發生錯誤,都會在隱含模型
中建立錯誤消息。其錯誤代碼前綴說明以下:
– required:必要的參數不存在。如 @RequiredParam(「param1」)
標註了一個入參,可是該參數不存在
– typeMismatch:在數據綁定時,發生數據類型不匹配的問題
– methodInvocation:Spring MVC 在調用處理方法時發生了錯誤
若你沒有使用BindingResult 或Errors 類型來存儲校驗失敗時的錯誤信息,則Spring MVC會直接拋出
org.springframework.validation.BindException
異常。因此你可使用Spring MVC的異常處理來捕獲此類異常並獲取你配置的校驗未經過信息:
須要特別注意的是:以上@Valid註解在了沒有使用@RequestBody註解的參數上,
若@Valid註解在了使用@RequestBody註解的參數上(即參數對象經過Json字符串反序列化生成),假若校驗未經過將會拋出org.springframework.web.bind.MethodArgumentNotValidException異常,你一樣能夠捕獲該異常:
關於使用Spring MVC的異常處理請參考博客:
http://www.javashuo.com/article/p-szcbrgmf-eg.html
轉載請註明出處