天天看點

SpringMVC 使用驗證架構 Bean Validation(上)

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/catoop/article/details/51278675

對于任何一個應用而言在用戶端做的資料有效性驗證都不是安全有效的,這時候就要求我們在開發的時候在服務端也對資料的有效性進行驗證。 SpringMVC 自身對資料在服務端的校驗(Hibernate Validator)有一個比較好的支援,它能将我們送出到服務端的資料按照我們事先的約定進行資料有效性驗證,對于不合格的資料資訊 SpringMVC 會把它儲存在錯誤對象中(Errors接口的子類),這些錯誤資訊我們也可以通過 SpringMVC 提供的标簽(form:errors)在前端JSP頁面上進行展示。或者使用攔截器 after 方法對處理錯誤資訊進行處理後傳遞給頁面(我們使用JSON請求的時候就需要這樣做)。

本文來介紹,如何在 SpringMVC 中進行 Validator 的使用。

一、添加POM依賴

<!-- Hibernate Validator -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>
           

二、配置要驗證的實體

public class ValidatorTest {

    // message 直接提供錯誤資訊
    @NotNull(message = "username 不能為空")
    // message 使用 {} 代表錯誤内容,從 resources 目錄下的 ValidationMessages.properties 檔案中讀取
    @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "{user.username.illegal}") 
    private String username;

    @Size(min = 5, max = 10, message = "{password.length.illegal}")
    private String password;

    // 省略 get\set   

}           

ValidationMessages.properties 檔案内容:

user.username.illegal=使用者名格式不正确
password.length.illegal=密碼[${validatedValue}]長度必須為{min}到{max}個字元

其中${validatedValue} 用來擷取預校驗屬性的值。
{min} 和 {max} 用來讀取 @Size 注解中對應的屬性值。
你還可以像 ${max > 1 ? '大于1' : '小于等于1'} 這樣使用el表達式。
另外我們還可以拿到一個java.util.Formatter類型的formatter變量進行格式化:
${formatter.format("%04d", min)}             

如果EL表達式不起作用,可以添加如下依賴嘗試,如果沒有問題請忽略。

<dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>2.2.4</version>
            <scope>provided</scope>
        </dependency>           

内置的驗證限制注解

内置的驗證限制注解如下表所示(摘自hibernate validator reference):

驗證注解 驗證的資料類型 說明
@AssertFalse Boolean,boolean 驗證注解的元素值是false
@AssertTrue 驗證注解的元素值是true
@NotNull 任意類型 驗證注解的元素值不是null
@Null 驗證注解的元素值是null
@MIN(value=值) BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存儲的是數字)子類型 驗證注解的元素值大于等于@Min指定的value值
@MAX(value=值) 和@Min要求一樣 驗證注解的元素值小于等于@Max指定的value值
@DecimalMin(value=值) 驗證注解的元素值大于等于@ DecimalMin指定的value值
@DecimalMax(value=值) 驗證注解的元素值小于等于@ DecimalMax指定的value值
@Digits(integer=整數位數, fraction=小數位數) 驗證注解的元素值的整數位數和小數位數上限
@Size(min=下限, max=上限) 字元串、Collection、Map、數組等 驗證注解的元素值的在min和max(包含)指定區間之内,如字元長度、集合大小
@Past java.util.Date,java.util.Calendar;Joda Time類庫的日期類型 驗證注解的元素值(日期類型)比目前時間早
@Future 與@Past要求一樣 驗證注解的元素值(日期類型)比目前時間晚
@NotBlank CharSequence子類型 驗證注解的元素值不為空(不為null、去除首位空格後長度為0),不同于@NotEmpty,@NotBlank隻應用于字元串且在比較時會去除字元串的首位空格
@Length(min=下限, max=上限) 驗證注解的元素值長度在min和max區間内
@NotEmpty CharSequence子類型、Collection、Map、數組 驗證注解的元素值不為null且不為空(字元串長度不為0、集合大小不為0)
@Range(min=最小值, max=最大值) BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類型和包裝類型 驗證注解的元素值在最小值和最大值之間
@Email(regexp=正規表達式,flag=标志的模式) CharSequence子類型(如String) 驗證注解的元素值是Email,也可以通過regexp和flag指定自定義的email格式
@Pattern(regexp=正規表達式,flag=标志的模式) String,任何CharSequence的子類型 驗證注解的元素值與指定的正規表達式比對
@Valid 任何非原子類型 指定遞歸驗證關聯的對象;如使用者對象中有個位址對象屬性,如果想在驗證使用者對象時一起驗證位址對象的話,在位址對象上加@Valid注解即可級聯驗證

三、Controller 實體驗證與視圖錯誤資訊的展示

JSP 頁面:

錯誤資訊使用 form:errors 展示,這個标簽,必須放在 form:form 中使用。

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Java驗證架構測試</title>
  </head>

  <body>
    <form:form method="post" modelAttribute="testModel" action="${pageContext.request.contextPath }/validator/test3">
        <h1><form:errors path="username" /></h1><!-- path的值可以為 * ,表示顯示所有錯誤 -->
        <h1><form:errors path="password" /></h1>
        <form:input path="username" /><br/>
        <form:input path="password" /><br/>
        <input type="submit" value="送出"/>
    </form:form>
  </body>
</html>           

對應的 Controller 的方法:

@Controller
@RequestMapping("/validator")
public class ValidatorController {

    /**
     * 響應到JSP頁面
     * 
     * @param test
     * @param result 
     *      這裡的BindingResult必須緊挨着@Valid參數的,即必須緊挨着需要校驗的參數,
     *      這就意味着我們有多少個@Valid參數就需要有多少個對應的Errors參數,它們是一一對應的。
     * @return
     * @author SHANHY
     * @create  2016年4月14日
     */
    @RequestMapping("/test3")
    public String test3(@Valid @ModelAttribute("testModel") ValidatorTest test, 
            BindingResult result, Model model){
        model.addAttribute("test", test);
        if(result.hasErrors())
            return "validator1";
        return "validator2";
    }
}           

後面文章将接着介紹:

四、Controller 普通參數驗證與視圖錯誤資訊的展示

五、JSON 請求響應錯誤資訊

六、錯誤資訊的配置檔案

七、錯誤資訊中使用EL表達式

八、一個手工驗證的工具類