項目中,通常使用較多的是前端的校驗,比如頁面中js校驗以及form表單使用bootstrap校驗。然而對于安全要求較高點建議在服務端進行校驗。
服務端校驗:
- 控制層controller:校驗頁面請求的參數的合法性。在服務端控制層controller校驗,不區分客戶端類型。
- 業務層service(使用較多):主要校驗關鍵業務參數,僅限于service接口中使用的參數。
- 持久層dao:一般是不校驗的。
環境集成
1、添加jar包:
此處使用hibernate-validator實現(版本:hibernate-validator-4.3.0.Final-dist.zip),將如下jar包添加到classpath(WEB-INF/lib下即可):
- dist/lib/required/validation-api-1.0.0.GA.jar JSR-303規范API包
- dist/hibernate-validator-4.3.0.Final.jar Hibernate 參考實現
2、在spring配置總添加對JSR-303驗證框架的支持
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!-- 校驗錯誤信息配置文件 --> < bean id = "messageSource" class = "org.springframework.context.support.ReloadableResourceBundleMessageSource" > <!-- 資源文件名--> < property name = "basenames" > < list > < value >classpath:CustomValidationMessages</ value > </ list > </ property > <!-- 資源文件編碼格式 --> < property name = "fileEncodings" value = "utf-8" /> <!-- 對資源文件內容緩存時間,單位秒 --> < property name = "cacheSeconds" value = "120" /> </ bean > |
1
2
3
4
5
6
7
8
|
<!-- 校驗器 --> < bean id = "validator" class = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" > <!-- hibernate校驗器--> < property name = "providerClass" value = "org.hibernate.validator.HibernateValidator" /> <!-- 指定校驗使用的資源文件,在文件中配置校驗錯誤信息,如果不指定則默認使用classpath下的ValidationMessages.properties --> < property name = "validationMessageSource" ref = "messageSource" /> </ bean > |
自動注冊validator
1
2
|
< mvc:annotation-driven conversion-service = "conversionService" validator = "validator" > </ mvc:annotation-driven > |
例子說明
例子一:
1
2
3
4
5
|
import javax.validation.constraints.NotNull; public class UserModel { @NotNull (message= "{username.not.empty}" ) private String username; } |
通過@NotNull指定此username字段不允許為空,當驗證失敗時將從之前指定的messageSource中獲取“username.not.empty”對于的錯誤信息,此處只有通過“{錯誤消息鍵值}”格式指定的才能從messageSource獲取。
1
2
3
4
5
6
7
8
9
10
11
|
@Controller public class HelloWorldController { @RequestMapping ( "/validate/hello" ) public String validate( @Valid @ModelAttribute ( "user" ) UserModel user, Errors errors) { if (errors.hasErrors()) { return "validate/error" ; } return "redirect:/success" ; } } |
通過在命令對象上注解@Valid來告訴Spring MVC此命令對象在綁定完畢后需要進行JSR-303驗證,如果驗證失敗會將錯誤信息添加到errors錯誤對象中。
驗證失敗后需要展示的頁面(/WEB-INF/jsp/error.jsp)
1
2
3
4
5
6
|
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %> <% @taglib prefix= "form" uri= "http://www.springframework.org/tags/form" %> <form:form commandName= "user" > <form:errors path= "*" cssStyle= "color:red" ></form:errors><br/> </form:form> |
在瀏覽器地址欄中輸入http://localhost:8080/validate/hello,即沒有username數據,請求后將直接到驗證失敗界面并顯示錯誤消息“用戶名不能為空”,如果請求時帶上“?username=zhang”將重定向到成功頁面。
例子二:
1
2
3
4
5
6
7
8
9
10
|
public class Items { private Integer id; @Size (min= 1 ,max= 20 ,message= "{items.name.length.error}" ) private String name; @NotNull (message= "{items.createtime.isNULL}" ) private Date createtime; 省略set()和get()... } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public String editItemsSubmit(Model model, @Validated Items items, BindingResult bindingResult) throws Exception { if (bindingResult.hasErrors()){ List<ObjectError> allErrors = bindingResult.getAllErrors(); for (ObjectError objectError:allErrors) { System.out.println(objectError.getDefaultMessage()); } //可以直接使用model將提交pojo回顯到頁面 model.addAttribute( "items" ,items); // 出錯重新到商品修改頁面 return "items/editItems" ; } return "success" ; } |
1
2
3
4
5
6
7
8
9
|
< table width = "100%" border = 1 > < tr > < td >商品名稱</ td > < td >< form:input type = "text" path = "items.name" value = "${items.name }" /></ td >< form:errors path = "items.name" /> </ tr > < tr > < td >商品生產日期</ td > < td >< input type = "text" name = "createtime" value = "<fmt:formatDate value=" ${items.createtime}" pattern = "yyyy-MM-dd HH:mm:ss" />"/></ td > </ tr > |
然后jsp頁面還是之前的頁面,并能顯示輸入不合法的并通過<form:errors path="items.name"/>顯示出來,這樣明顯更加簡單。
當我們配置了messageSource Bean時,默認將為驗證的對象自動生成如下錯誤消息鍵:
- 驗證錯誤注解簡單類名.驗證對象名.字段名
- 驗證錯誤注解簡單類名.字段名
- 驗證錯誤注解簡單類名.字段類型全限定類名
- 驗證錯誤注解簡單類名
使用的優先級是:從高到低,即最前邊的具有最高的優先級,而且以上所有默認的錯誤消息鍵優先級高于自定義的錯誤消息鍵。
如測試用例
public String pattern(@Valid @ModelAttribute(“model”) PatternModel model, Errors errors)
將自動產生如下錯誤消息鍵:
- Pattern.model.value=驗證錯誤注解簡單類名.驗證對象名.字段名
- Pattern.value=驗證錯誤注解簡單類名.字段名
- Pattern.Java.lang.String=驗證錯誤注解簡單類名.字段類型全限定類名
- Pattern=驗證錯誤注解簡單類名
內置的驗證約束注解如下表所示(摘自hibernate validator reference):
驗證注解 | 驗證的數據類型 | 說明 |
---|---|---|
@AssertFalse | Boolean,boolean | 驗證注解的元素值是false |
@AssertTrue | Boolean,boolean | 驗證注解的元素值是true |
@NotNull | 任意類型 | 驗證注解的元素值不是null |
@Null | 任意類型 | 驗證注解的元素值是null |
@Min(value=值) | BigDecimal,BigInteger, byte, short, int, long,等任何Number或CharSequence(存儲的是數字)子類型 | 驗證注解的元素值大于等于@Min指定的value值 |
@Max(value=值) | 和@Min要求一樣 | 驗證注解的元素值小于等于@Max指定的value值 |
@DecimalMin(value=值) | 和@Min要求一樣 | 驗證注解的元素值大于等于@ DecimalMin指定的value值 |
@DecimalMax(value=值) | 和@Min要求一樣 | 驗證注解的元素值小于等于@ DecimalMax指定的value值 |
@Digits(integer=整數位數, fraction=小數位數) | 和@Min要求一樣 | 驗證注解的元素值的整數位數和小數位數上限 |
@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=上限) | CharSequence子類型 | 驗證注解的元素值長度在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注解即可級聯驗證 |
此處只列出Hibernate Validator提供的大部分驗證約束注解,請參考hibernate validator官方文檔了解其他驗證約束注解和進行自定義的驗證約束注解定義。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/bear_wr/article/details/52367928