九、SpringMVC 数据校验
一般情况下,用户的输入是随意的,为了保证数据的合法性,数据验证是所有 Web 应用必须处理的问题。
B/S系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑。但是在一些安全性要求高的系统中服务端校验是不可缺少的,SpringMVC实现控制层添加校验。
Spring MVC 有以下两种方法可以验证输入:
利用 Spring 自带的验证框架
利用 JSR 303 实现
数据验证分为客户端验证和服务器端验证,客户端验证主要是过滤正常用户的误操作,通过 JavaScript 代码完成。服务器端验证是整个应用阻止非法数据的最后防线,通过在应用中编程实现。
本章使用 JSR 303 实现服务器端的数据验证。
JSR 303 是 Java 为 Bean 数据合法性校验所提供的标准框架。JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证。
JSR 303 不需要编写验证器,它定义了一套可标注在成员变量、属性方法上的校验注解,9.4章节所示。
Spring MVC 支持 JSR 303 标准的校验框架,Spring 的 DataBinder 在进行数据绑定时,可同时调用校验框架来完成数据校验工作,非常简单方便。在 Spring MVC 中,可以直接通过注解驱动的方式来进行数据校验。
Spring 本身没有提供 JSR 303 的实现,Hibernate Validator 实现了 JSR 303,所以必须在项目中加入来自 Hibernate Validator 库的 jar 文件(和Hibernate ORM没有任何关系)。
9.1 前端校验
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>数据验证</h1>
<p><a href="views/front.jsp">前端验证</a></p>
<p><a href="views/add.jsp">员工新增</a></p>
<p><a href="views/edit.jsp">员工编辑</a></p>
</div>
</body>
</html>
front.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
//客户端验证
//优点:快捷,减轻服务器的压力
//缺点:可控制性低(比如浏览器设置->网站设置->禁用JS,那么前端校验就无效了。或者第三方工具发送请求)
function doValidate(){
var ename = $('#ename').val().trim();
var job = $('#job').val().trim();
var sal = $('#sal').val().trim();
//if(!ename){
if(ename==null || ename==''){
alert('员工姓名不能为空');
return false;
}
var reg1 = /^\S{2,8}$/;
if(!reg1.test(ename)){
alert('员工姓名必须为2~8位非空白字符');
return false;
}
if(job==null || job==''){
alert('员工岗位不能为空');
return false;
}
if(sal==null || sal==''){
alert('员工薪资不能为空');
return false;
}
var reg2 = /^\d+(.\d{1,2})?$/;
if(!reg2.test(sal)){
alert('员工薪资必须为整数或两位小数');
return false;
}
return true;
}
</script>
</head>
<body>
<div style="text-align: center;">
<h3>前端验证</h3>
<form action="views/success.jsp" method="post" onsubmit="return doValidate()" >
<p>员工姓名:<input type="text" id="ename" name="ename"></p>
<p>员工岗位:<input type="text" id="job" name="job"></p>
<p>员工薪资:<input type="text" id="sal" name="sal"></p>
<p><button>提交</button></p>
</form>
</div>
</body>
</html>
success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>操作成功</h1>
</div>
</body>
</html>
9.2 导入数据校验jar包
方式一:引入jar包
方式二:maven依赖配置
<dependencies>
<!-- spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springbean包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springcontext包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring表达式包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAOP包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAspects包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring对web的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springwebMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- 配置javaweb环境 -->
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
<!-- Hibernate Validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
</dependencies>
9.3 SpringMVC配置
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--字符编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 通过隐藏域传参解决form表单的PUT与DELETE方式的请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 解决put请求传递参数的问题-->
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/views/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
springmvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- springmvc的注解式开发 -->
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.newcapec"/>
<!-- MVC注解驱动 -->
<mvc:annotation-driven validator="validator"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置视图地址的前缀和后缀:简化视图地址 -->
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--不拦截静态资源-->
<mvc:default-servlet-handler/>
<!-- 配置springmvc的数据校验器-->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 配置hibernate-validator框架中的数据校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
</bean>
</beans>
9.4 校验注解规则
9.4.1 Bean Validator内置的注解
校验注解 | 校验的数据类型 | 说明 |
---|---|---|
@AssertFalse | Boolean,boolean | 被注释的元素值必须为false |
@AssertTrue | Boolean,boolean | 被注释的元素值必须为true |
@DecimalMax(value) | BigDecimal,BigInteger,byte,short,int,long以及基本数据类型相应的包装类,任何Number的子类型,String(由String表示的数值) | 被注释的元素值必须小于等于@DecimalMax指定的value值 |
@DecimalMin(value) | 和@DecimalMax要求一样 | 被注释的元素值必须大于等于@DecimalMin指定的value值 |
@Digits (integer=整数位, fraction=小数位) | 和@DecimalMax要求一样 | 被注释的元素值的整数位数和小数位数上限 |
@Future | java.util.Date,java.util.Calendar,Joda Time类库的日期类型 | 被注释的元素值必须比当前时间晚 |
@Max(value) | 和@DecimalMax要求一样 | 被注释的元素值必须小于等于@Max指定的value值 |
@Min(value) | 和@DecimalMax要求一样 | 被注释的元素值必须大于等于@Min指定的value值 |
@NotNull | 任意类型 | 被注释的元素值必须不为null |
@Null | 任意类型 | 被注释的元素值必须为null |
@Past | 和@Future要求一样 | 被注释的元素值必须比当前时间早 |
@Pattern(regex=正则表达式,flag=标志模式) | 字符串 | 被注释的元素值必须符合指定的正则表达式 |
@Size(max=, min=) | 字符串,Collection集合,Map集合,数组 | 被注释的元素值的大小必须在指定的范围内 |
9.4.2 Hibernate Validator拓展的注解
校验注解 | 校验的数据类型 | 说明 |
---|---|---|
字符串 | 被注释的元素值必须是电子邮箱地址 | |
@Length(min=,max=) | 字符串 | 被注释的元素值的大小必须在指定的范围内 |
@NotBlank | 字符串 | 被注释的元素值必须非空,非空值或非全空白字符。功能强大于@NotEmpty |
@NotEmpty | 字符串,Collection集合,Map集合,数组 | 被注释的元素值必须非空或非空值。功能强于@NotNull |
@Range(min=,max=) | BigDecimal,BigInteger,byte,short,int,long以及基本数据类型相应的包装类 | 被注释的元素值必须在合适的范围内 |
9.5 添加校验规则
Hibernate Validator是通过注解的方式对实体类中的成员变量进行校验,即在成员变量上配置校验规则。
/**
* hibernate validator数据验证框架
* 作用:通过注解的方式进行数据验证,注解需要添加在实体的成员变量上
*
* 注解中通过的属性:
* message: 当前验证失败时给用户提示信息
*/
public class Emp {
private Integer empno;
@NotBlank(message = "员工姓名不能为空")
@Length(message = "员工姓名必须为2~8位字符", min = 2, max = 8)
private String ename;
@NotBlank(message = "员工岗位不能为空")
private String job;
@NotNull(message = "员工薪资不能为空")
@DecimalMin(message = "员工薪资不能低于1000", value = "1000")
private Double sal;
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", sal=" + sal +
'}';
}
}
9.6 捕获校验错误信息
@Controller
@RequestMapping("/emp")
public class EmpController {
/**
* 开启数据验证
*
* @Validated 位置:形参
* 作用:开启了请求参数的验证
*
* 注意:@Validated注解不能单独使用,需要在每个开启数据验证的形参后,跟随一个BindingResult类型的形参
* BindingResult:判断数据是否验证通过,并接收验证失败信息
*/
@RequestMapping("/add")
public String add(@Validated Emp emp, BindingResult bindingResult, Model model) {
System.out.println(emp);
//判断数据验证是否通过
if (bindingResult.hasErrors()) {
//数据验证没有全部通过
List<ObjectError> list = bindingResult.getAllErrors();
for (ObjectError objectError : list) {
//getDefaultMessage()获取验证失败信息
System.out.println(objectError.getDefaultMessage());
}
model.addAttribute("errors", list);
return "add";
}
return "success";
}
}
注意:@Validated表示在对Controller方法形参绑定时进行校验,校验信息写入BindingResult中,在要校验的实体类后边添加BingdingResult,一个BindingResult对应一个实体类,且BingdingResult放在实体类的后边。
9.7 在页面显示校验错误信息
在Controller中已经把错误列表对象存入作用域中,在页面直接取出,遍历并显示即可。
add.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h3>员工新增</h3>
<div style="color: red;">
<ol>
<c:forEach items="${errors}" var="e">
<li>${e.defaultMessage}</li>
</c:forEach>
</ol>
</div>
<form action="emp/add" method="post">
<p>员工姓名:<input type="text" name="ename"></p>
<p>员工岗位:<input type="text" name="job"></p>
<p>员工薪资:<input type="text" name="sal"></p>
<p><button>提交</button></p>
</form>
</div>
</body>
</html>
9.8 分组校验
如果两处校验使用同一个实体类则可以设定校验分组,通过分组校验可以对每处的校验个性化。
9.8.1 定义分组标识
定义分组标识,就是定义一个空接口:
public interface EmpAddValidator {
}
public interface EmpEditValidator {
}
9.8.2 在校验规则中添加分组
/**
* hibernate validator数据验证框架
* 是通过注解的方式对数据进行验证
* 注解需要添加在实体类的属性上,因为在springmvc中是通过实体类类型的形参接收请求参数
*
* 注解中通用的属性:
* message: 当前验证失败是给用户的提交信息
* groups: 分组校验
*/
public class Emp {
@NotNull(message = "员工编号不能为空", groups = EmpEditValidator.class)
private Integer empno;
// @NotBlank(message = "员工姓名不能为空")
@NotBlank(message = "员工姓名不能为空", groups = {
EmpEditValidator.class, EmpAddValidator.class})
// @Length(message = "员工姓名必须为2~8位字符",min = 2, max = 8)
@Length(message = "员工姓名必须为2~8个字符", min = 2, max = 8, groups = {
EmpEditValidator.class, EmpAddValidator.class})
private String ename;
// @NotBlank(message = "员工岗位不能为空")
@NotBlank(message = "员工岗位不能为空", groups = {
EmpEditValidator.class, EmpAddValidator.class})
private String job;
// @NotNull(message = "员工薪资不能为空")
@NotNull(message = "员工薪资不能为空", groups = {
EmpEditValidator.class, EmpAddValidator.class})
// @DecimalMin(message = "员工薪资不能低于1000",value = "1000")
@DecimalMin(message = "员工薪资不能低于1000", value = "1000", groups = {
EmpEditValidator.class, EmpAddValidator.class})
private Double sal;
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", sal=" + sal +
'}';
}
}
9.8.3 在@Validated注解中指定分组
@Controller
@RequestMapping("/emp")
public class EmpController {
/**
* 开启数据验证
*
* @Validated 位置:形参
* 作用:开启了请求参数的验证
* 属性:指定分组
*
* 注意:@Validated注解不能单独使用,需要在每个开启数据验证的形参后,跟随一个BindingResult类型的形参
* BindingResult:判断数据是否验证通过,并接收验证失败信息
*/
@RequestMapping("/add")
public String add(@Validated(EmpAddValidator.class) Emp emp, BindingResult bindingResult, Model model) {
System.out.println(emp);
//判断数据验证是否通过
if (bindingResult.hasErrors()) {
//数据验证没有全部通过
List<ObjectError> list = bindingResult.getAllErrors();
for (ObjectError objectError : list) {
//getDefaultMessage()获取验证失败信息
System.out.println(objectError.getDefaultMessage());
}
model.addAttribute("errors", list);
return "add";
}
return "success";
}
@RequestMapping("/edit")
public String edit(@Validated(EmpEditValidator.class) Emp emp, BindingResult bindingResult, Model model) {
System.out.println(emp);
//判断数据验证是否通过
if (bindingResult.hasErrors()) {
//数据验证没有全部通过
List<ObjectError> list = bindingResult.getAllErrors();
model.addAttribute("errors", list);
return "edit";
}
return "success";
}
}
9.8.4 编辑页面
edit.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h3>员工编辑</h3>
<div style="color: red;">
<ol>
<c:forEach items="${errors}" var="e">
<li>${e.defaultMessage}</li>
</c:forEach>
</ol>
</div>
<form action="emp/edit" method="post">
<p>员工编号:<input type="text" name="empno"></p>
<p>员工姓名:<input type="text" name="ename"></p>
<p>员工岗位:<input type="text" name="job"></p>
<p>员工薪资:<input type="text" name="sal"></p>
<p><button>提交</button></p>
</form>
</div>
</body>
</html>
9.9 错误提示信息资源文件
9.9.1 资源文件
当属性值校验失败后,其提示信息可配置在一个资源文件中,文件名称默认为classpath:ValidationMessages.properties:
emp.empno.NotNull=员工编号不能为空--2
emp.ename.NotBlank=员工姓名不能为空--2
emp.ename.Length=员工姓名必须为2~8位字符--2
emp.job.NotBlank=员工岗位不能为空--2
emp.salary.NotNull=员工薪资不能为空--2
emp.salary.DecimalMin=员工薪资不能低于1000--2
9.9.2 实体类
在实体中通过{}引用资源文件中的数据:
/**
* hibernate validator数据验证框架
* 是通过注解的方式对数据进行验证
* 注解需要添加在实体类的属性上,因为在springmvc中是通过实体类类型的形参接收请求参数
* <p>
* 注解中通用的属性:
* message : 当前验证失败是给用户的提交信息
* groups : 分组校验
*/
public class Emp {
// @NotNull(message = "员工编号不能为空",groups= EmpEditValidator.class)
@NotNull(message = "{emp.empno.NotNull}", groups = EmpEditValidator.class)
private Integer empno;
// @NotBlank(message = "员工姓名不能为空")
// @NotBlank(message = "员工姓名不能为空",groups= {EmpEditValidator.class, EmpAddValidator.class})
@NotBlank(message = "{emp.ename.NotBlank}", groups = {
EmpEditValidator.class, EmpAddValidator.class})
// @Length(message = "员工姓名必须为2~8位字符",min = 2, max = 8)
// @Length(message = "员工姓名必须为2~8个字符", min = 2, max = 8,groups= {EmpEditValidator.class, EmpAddValidator.class})
@Length(message = "{emp.ename.Length}", min = 2, max = 8, groups = {
EmpEditValidator.class, EmpAddValidator.class})
private String ename;
// @NotBlank(message = "员工岗位不能为空")
// @NotBlank(message = "员工岗位不能为空",groups= {EmpEditValidator.class, EmpAddValidator.class})
@NotBlank(message = "{emp.job.NotBlank}", groups = {
EmpEditValidator.class, EmpAddValidator.class})
private String job;
// @NotNull(message = "员工薪资不能为空")
// @NotNull(message = "员工薪资不能为空",groups= {EmpEditValidator.class, EmpAddValidator.class})
@NotNull(message = "{emp.salary.NotNull}", groups = {
EmpEditValidator.class, EmpAddValidator.class})
// @DecimalMin(message = "员工薪资不能低于1000",value = "1000")
// @DecimalMin(message = "员工薪资不能低于1000", value = "1000", groups = {EmpEditValidator.class, EmpAddValidator.class})
@DecimalMin(message = "{emp.salary.DecimalMin}", value = "1000", groups = {
EmpEditValidator.class, EmpAddValidator.class})
private Double sal;
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", sal=" + sal +
'}';
}
}
9.9.3 配置
错误提示信息资源文件也可自定义名称和位置,配置如下:
<!-- 配置springmvc的数据校验器-->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 配置hibernate-validator框架中的数据校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 在springmvc的数据校验中,默认的资源文件classpath:ValidationMessages.properties -->
<!-- 指定校验使用的资源文件-->
<property name="validationMessageSource" ref="validationMessageSource"></property>
</bean>
<!-- 配置validationMessageSource -->
<bean id="validationMessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 指定校验信息的资源文件的基本文件名称,不包括后缀,后缀默认是properties -->
<property name="basenames">
<list>
<value>classpath:message</value>
</list>
</property>
<!-- 指定文件的编码
改属性为properties属性,键的值为文件名字加路径名,乱码需要在此处配置utf-8即可
-->
<property name="fileEncodings" >
<props>
<prop key="classpath:message">utf-8</prop>
</props>
</property>
<!-- 对资源文件内容缓存的时间,单位秒 -->
<property name="cacheSeconds" value="120"></property>
</bean>
Messages.properties -->