springmvc使用JSR-303進(jìn)行數(shù)據(jù)校驗(yàn)實(shí)例
項(xiàng)目中,通常使用較多的是前端的校驗(yàn),比如頁面中js校驗(yàn)以及form表單使用bootstrap校驗(yàn)。然而對(duì)于安全要求較高點(diǎn)建議在服務(wù)端進(jìn)行校驗(yàn)。
服務(wù)端校驗(yàn):
- 控制層controller:校驗(yàn)頁面請(qǐng)求的參數(shù)的合法性。在服務(wù)端控制層controller校驗(yàn),不區(qū)分客戶端類型。
- 業(yè)務(wù)層service(使用較多):主要校驗(yàn)關(guān)鍵業(yè)務(wù)參數(shù),僅限于service接口中使用的參數(shù)。
- 持久層dao:一般是不校驗(yàn)的。
環(huán)境集成
1、添加jar包:
此處使用hibernate-validator實(shí)現(xiàn)(版本: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規(guī)范API包
- dist/hibernate-validator-4.3.0.Final.jar Hibernate 參考實(shí)現(xiàn)
2、在spring配置總添加對(duì)JSR-303驗(yàn)證框架的支持
<!-- 校驗(yàn)錯(cuò)誤信息配置文件 --> <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" /> <!-- 對(duì)資源文件內(nèi)容緩存時(shí)間,單位秒 --> <property name="cacheSeconds" value="120" /> </bean>
<!-- 校驗(yàn)器 --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <!-- hibernate校驗(yàn)器--> <property name="providerClass" value="org.hibernate.validator.HibernateValidator" /> <!-- 指定校驗(yàn)使用的資源文件,在文件中配置校驗(yàn)錯(cuò)誤信息,如果不指定則默認(rèn)使用classpath下的ValidationMessages.properties --> <property name="validationMessageSource" ref="messageSource" /> </bean>
自動(dòng)注冊(cè)validator
<mvc:annotation-driven conversion-service="conversionService" validator="validator"> </mvc:annotation-driven>
例子說明
例子一:
import javax.validation.constraints.NotNull;
public class UserModel {
@NotNull(message="{username.not.empty}")
private String username;
}
通過@NotNull指定此username字段不允許為空,當(dāng)驗(yàn)證失敗時(shí)將從之前指定的messageSource中獲取“username.not.empty”對(duì)于的錯(cuò)誤信息,此處只有通過“{錯(cuò)誤消息鍵值}”格式指定的才能從messageSource獲取。
@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";
}
}
通過在命令對(duì)象上注解@Valid來告訴Spring MVC此命令對(duì)象在綁定完畢后需要進(jìn)行JSR-303驗(yàn)證,如果驗(yàn)證失敗會(huì)將錯(cuò)誤信息添加到errors錯(cuò)誤對(duì)象中。
驗(yàn)證失敗后需要展示的頁面(/WEB-INF/jsp/error.jsp)
<%@ 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數(shù)據(jù),請(qǐng)求后將直接到驗(yàn)證失敗界面并顯示錯(cuò)誤消息“用戶名不能為空”,如果請(qǐng)求時(shí)帶上“?username=zhang”將重定向到成功頁面。
例子二:
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()...
}
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);
// 出錯(cuò)重新到商品修改頁面
return "items/editItems";
}
return "success";
}
<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>商品生產(chǎn)日期</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"/>顯示出來,這樣明顯更加簡單。
當(dāng)我們配置了messageSource Bean時(shí),默認(rèn)將為驗(yàn)證的對(duì)象自動(dòng)生成如下錯(cuò)誤消息鍵:
- 驗(yàn)證錯(cuò)誤注解簡單類名.驗(yàn)證對(duì)象名.字段名
- 驗(yàn)證錯(cuò)誤注解簡單類名.字段名
- 驗(yàn)證錯(cuò)誤注解簡單類名.字段類型全限定類名
- 驗(yàn)證錯(cuò)誤注解簡單類名
使用的優(yōu)先級(jí)是:從高到低,即最前邊的具有最高的優(yōu)先級(jí),而且以上所有默認(rèn)的錯(cuò)誤消息鍵優(yōu)先級(jí)高于自定義的錯(cuò)誤消息鍵。
如測(cè)試用例
public String pattern(@Valid @ModelAttribute(“model”) PatternModel model, Errors errors)
將自動(dòng)產(chǎn)生如下錯(cuò)誤消息鍵:
- Pattern.model.value=驗(yàn)證錯(cuò)誤注解簡單類名.驗(yàn)證對(duì)象名.字段名
- Pattern.value=驗(yàn)證錯(cuò)誤注解簡單類名.字段名
- Pattern.Java.lang.String=驗(yàn)證錯(cuò)誤注解簡單類名.字段類型全限定類名
- Pattern=驗(yàn)證錯(cuò)誤注解簡單類名
內(nèi)置的驗(yàn)證約束注解如下表所示(摘自hibernate validator reference):
| 驗(yàn)證注解 | 驗(yàn)證的數(shù)據(jù)類型 | 說明 |
|---|---|---|
| @AssertFalse | Boolean,boolean | 驗(yàn)證注解的元素值是false |
| @AssertTrue | Boolean,boolean | 驗(yàn)證注解的元素值是true |
| @NotNull | 任意類型 | 驗(yàn)證注解的元素值不是null |
| @Null | 任意類型 | 驗(yàn)證注解的元素值是null |
| @Min(value=值) | BigDecimal,BigInteger, byte, short, int, long,等任何Number或CharSequence(存儲(chǔ)的是數(shù)字)子類型 | 驗(yàn)證注解的元素值大于等于@Min指定的value值 |
| @Max(value=值) | 和@Min要求一樣 | 驗(yàn)證注解的元素值小于等于@Max指定的value值 |
| @DecimalMin(value=值) | 和@Min要求一樣 | 驗(yàn)證注解的元素值大于等于@ DecimalMin指定的value值 |
| @DecimalMax(value=值) | 和@Min要求一樣 | 驗(yàn)證注解的元素值小于等于@ DecimalMax指定的value值 |
| @Digits(integer=整數(shù)位數(shù), fraction=小數(shù)位數(shù)) | 和@Min要求一樣 | 驗(yàn)證注解的元素值的整數(shù)位數(shù)和小數(shù)位數(shù)上限 |
| @Size(min=下限, max=上限) | 字符串、Collection、Map、數(shù)組等 | 驗(yàn)證注解的元素值的在min和max(包含)指定區(qū)間之內(nèi),如字符長度、集合大小 |
| @Past | java.util.Date, java.util.Calendar; Joda Time類庫的日期類型 | 驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間早 |
| @Future | 與@Past要求一樣 | 驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間晚 |
| @NotBlank | CharSequence子類型 | 驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會(huì)去除字符串的首位空格 |
| @Length(min=下限, max=上限) | CharSequence子類型 | 驗(yàn)證注解的元素值長度在min和max區(qū)間內(nèi) |
| @NotEmpty | CharSequence子類型、Collection、Map、數(shù)組 | 驗(yàn)證注解的元素值不為null且不為空(字符串長度不為0、集合大小不為0) |
| @Range(min=最小值, max=最大值) | BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類型和包裝類型 | 驗(yàn)證注解的元素值在最小值和最大值之間 |
| @Email(regexp=正則表達(dá)式,flag=標(biāo)志的模式) | CharSequence子類型(如String) | 驗(yàn)證注解的元素值是Email,也可以通過regexp和flag指定自定義的email格式 |
| @Pattern(regexp=正則表達(dá)式,flag=標(biāo)志的模式) | String,任何CharSequence的子類型 | 驗(yàn)證注解的元素值與指定的正則表達(dá)式匹配 |
| @Valid | 任何非原子類型 | 指定遞歸驗(yàn)證關(guān)聯(lián)的對(duì)象;如用戶對(duì)象中有個(gè)地址對(duì)象屬性,如果想在驗(yàn)證用戶對(duì)象時(shí)一起驗(yàn)證地址對(duì)象的話,在地址對(duì)象上加@Valid注解即可級(jí)聯(lián)驗(yàn)證 |
此處只列出Hibernate Validator提供的大部分驗(yàn)證約束注解,請(qǐng)參考hibernate validator官方文檔了解其他驗(yàn)證約束注解和進(jìn)行自定義的驗(yàn)證約束注解定義。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot中登錄后關(guān)于cookie和session攔截問題的案例分析
這篇文章主要介紹了Springboot中登錄后關(guān)于cookie和session攔截案例,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
基于mybatis查詢結(jié)果映射不到對(duì)象的處理
這篇文章主要介紹了mybatis查詢結(jié)果映射不到對(duì)象的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Mybatis-plus獲取雪花算法生成的ID并返回生成ID
本文主要介紹了Mybatis-plus獲取雪花算法生成的ID并返回生成ID,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09
Jpa 如何使用@EntityListeners 實(shí)現(xiàn)實(shí)體對(duì)象的自動(dòng)賦值
這篇文章主要介紹了Jpa 如何使用@EntityListeners 實(shí)現(xiàn)實(shí)體對(duì)象的自動(dòng)賦值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
MySQL數(shù)據(jù)文件直接通過拷貝備份與恢復(fù)的操作方法
這篇文章主要介紹了MySQL數(shù)據(jù)文件直接通過拷貝備份與恢復(fù)的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
MyEclipse2018中安裝Mybatis generator插件的實(shí)現(xiàn)步驟
這篇文章主要介紹了MyEclipse2018中安裝Mybatis generator插件的實(shí)現(xiàn)步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02

