如何使用SpringMVC進行數據校驗

前言:

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          被註釋的元素必須在合適的範圍內
 數組

一,準備Jar包:

使用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>

測試結果以下:

Tips:

• <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

 

轉載請註明出處

相關文章
相關標籤/搜索