Spring MVC 表單驗證
1. 前言
本節(jié)課講解 Spring MVC 提供的驗證框架,這個驗證框架屬于服務器端驗證模式。通過本章節(jié)內(nèi)容的學習,你將理解 JSR 概念,并能學到驗證框架所提供的注解。
本章節(jié)重點是掌握 JSR 驗證框架的使用;難點是理解其實現(xiàn)原理。
2. JSR
數(shù)據(jù)驗證是對數(shù)據(jù)進行邏輯處理之前需要進行的一個很重要環(huán)節(jié),如果不合要求的數(shù)據(jù)進入邏輯處理環(huán)節(jié)后,會導致程序的崩潰。
WEB 應用程序中,驗證用戶提交的表單數(shù)據(jù)的合法性既可以在客戶端實現(xiàn),也可以在服務器端實現(xiàn)。
- 客戶端驗證: 表單提交之前,通過客戶端的 JS 腳本對表單中預提交的數(shù)據(jù)進行驗證;
- 服務器端驗證: 數(shù)據(jù)提交到服務器后,由服務器端的的代碼進行驗證。
對于非敏感性的數(shù)據(jù)可以在客戶端驗證,如一些常規(guī)性的輸入格式要求驗證、類似于密碼長度要多少、信息不能為空等。
服務器端相比較于客戶端驗證,會多出網(wǎng)絡流量消耗。但是,對于一些敏感性的數(shù)據(jù),比如身份證信息、銀行卡信息…… 還是需要交給服務器的。
Spring MVC 提供的有驗證框架,能夠在綁定請求包中的數(shù)據(jù)時,按開發(fā)者提出的格式驗證規(guī)則對數(shù)據(jù)進行驗證。Spring MVC 驗證框架的使用非常便利,只需要幾個注解就能輕松解決問題。
使用之前,有幾個概念先要交代清楚。
2.1 JSR 是什么
Tips: 不要看錯了,是 JSR 不是 JSP。
JSR: Java 官方提供的數(shù)據(jù)合法性標準驗證框架,它只是一個規(guī)范。現(xiàn)有多個版本:
- Bean Validation 2.0 (JSR 380) ;
- Bean Validation 1.1 (JSR 349);
- Bean Validation 1.0 (JSR 303)。
準確的講,Spring MVC 驗證框架只是集成了 JSR 驗證框架,并沒有太多自己的具體實現(xiàn)。 JSR 提供了很多驗證注解,一般放在要驗證的 Bean 類型的屬性前面。
- @Null: 被注解的屬性的值必須為空;
- @NotNull: 被注解的屬性的值可以不為空;
- @Min(value): 注解數(shù)字類型的屬性,其值大于等于指定的值;
- @Max(value): 注解數(shù)字類型的屬性,其值小于等于指定值;
- @Size(max, min): 注解的屬性值的大小必須是在給定的范圍內(nèi)(包括邊界數(shù)字);
- @Past: 注解日期類型屬性,必須是一個過去的日期;
- @Future: 注解日期類型屬性,必須是一個將來的日期;
- @Pattern(regexp): 使用正則表達式驗證屬性的值;
- @Length(min,max): 屬性值的長度在給定的范圍之內(nèi)(包括邊界數(shù)字)。
Tips: 更多的驗證注解大家可以查閱 JSR 官方文檔。
了解了這些注解后,現(xiàn)在開始使用。
2.2 使用驗證框架
2.2.1 驗證前的準備
打開項目中的 pom.xml 文件,添加 validation-api 依賴包,大家需要注意一下,包名是以 javax 開頭的。因為 Spring MVC 并沒有實現(xiàn) JSR 接口規(guī)范,這里選擇 hibernate-validator ;
Tips: hibernate-validator 是 Hibernate 提供的 JSR 具體實現(xiàn)模塊。
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
打開 WebConfig 配置類,通知 Spring MVC 創(chuàng)建 LocalValidatorFactoryBean 對象。可以使用這個工廠對象創(chuàng)建具體的實現(xiàn)了 JSR 規(guī)范的驗證器。
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
return localValidatorFactoryBean;
}
2.2.2 JSR 驗證流程
先設定一個需求:添加老師信息。
- 構(gòu)建一個 Teacher 類,并在 Teacher 類的相關屬性上添加對應注解;
public class Teacher {
@NotNull(message = "姓名不能為空")
private String name;
@Min(value = 22,message = "年齡不能小于 22 歲")
private Integer age;
Tips: JSR 注解有一個 message 屬性,用來保存錯誤提示信息。
- 編寫 teacher.html 頁面;
<form action="teacher/save" method="post">
老師姓名:<input type="text" value="" name="name"/>
<br/>
老師年齡:<input type="text" value="" name="age"/>
<br/>
<input type="submit" value="添加" name="btnSave"/>
<input type="reset" value="重置" name="btnReset"/>
</form>
- 編寫響應控制器;
@Controller
@RequestMapping("/teacher")
public class TeacherAction {
@RequestMapping(value = "/save",method = RequestMethod.POST)
public String register(@Valid Teacher teacher,BindingResult result) {
if (result.hasErrors()) {
return "fail";
}
return "success";
}
}
Tips: @Valid 注解表示在綁定數(shù)據(jù)之后對數(shù)據(jù)進行驗證。BindingResult 組件用來保存驗證過程中的錯誤信息。除了可以使用 BindingResult ,此處還可以使用 Errors 替代。
- 在瀏覽器中訪問到 teacher.html 頁面,輸入不符合規(guī)則的數(shù)據(jù)后提交(年齡小于 22 歲);
- 最后會在瀏覽器中看到。
如此,整個驗證過程完畢。
3. 顯示錯誤信息
前面的測試過程有一個遺憾,沒有看到錯誤信息,沒有明確的告訴使用者哪些數(shù)據(jù)輸入沒有符合驗證要求。
要實現(xiàn)這個功能,只需要在控制器中把錯誤信息保存到請求域,然后在頁面中顯示出來。
- 修改一下控制器中的代碼。比前面的代碼多了一個 ModelMap 對象,用于把錯誤信息保存到請求作用域中;
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String register(@Valid Teacher teacher, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
List<FieldError> fieldsErrors = result.getFieldErrors();
for (FieldError fieldError : fieldsErrors) {
model.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return "fail";
}
return "success";
}
Tips: 如果驗證失敗,錯誤提示信息會自動保存到 BindingResult 類型 。
- 在提交失敗的頁面中顯示錯誤。
<body>
老師注冊失敗原因!
<br/>
${name}
<br/>
${age}
</body>
Tips: EL 表達式中的 name、age 是表單提交時的參數(shù)名(也就是表單控件的名字)。
model.put (fieldError.getField (), fieldError.getDefaultMessage ()) 這行代碼會把錯誤信息以表單控件名為 key 保存在請求作用域中。
- 再次在瀏覽器中打開 teacher.html 頁面,輸入不符合規(guī)則的數(shù)據(jù),提交后在錯誤頁面中看到。
4. 小結(jié)
本節(jié)課程和大家講解了 Spring MVC 的驗證框架,需要知道以下 2 點:
- Spring MVC 驗證框架采用的是服務器端驗證模式;
- Spring MVC 框架集成了 JSR 驗證框架,并沒有提供具體的實現(xiàn),本課程使用的是 Hibernate 提供的 JSR 具體實現(xiàn)模塊。
Spring MVC 驗證框架以注解的方式對數(shù)據(jù)進行規(guī)則限制,方便,簡潔,但因是服務器端驗證,所以,對于一般性的、常規(guī)性的驗證建議放在客戶端完成。