一、数据校验
项目中,通常使用较多是前端的校验,比如页面中js校验。对于安全要求较高点建议在服务端进行校验。
服务端校验:
控制层conroller:校验页面请求的参数的合法性。在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)
业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。
持久层dao:一般是不校验的。
二、springmvc 中的validator校验
Springmvc本身没有校验功能,它使用hibernate的校验框架。
2.1 环境准备
注意:hibernate-validator 要与 springmvc jar版本 对应(不然会起冲突)
2.2 在applicationContext-mvc.xml 配置validator 校验器
<mvc:annotation-driven validator="validator"></mvc:annotation-driven>
<!-- 校验器 -->
<bean id="validator"
class="org.springframeork.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- hibernate校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean>
<!-- 校验错误信息配置文件 -->
<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>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀名 -->
<!-- <property name="prefix" value="/WEB-INF/view/"/>-->
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
2.3、将校验器注册到适配器中
<mvc:annotation-driven validator="validator"></mvc:annotation-driven>
2.4、ValidationMessages.properties的配置
2.5 在pojo中添加校验规则
@Component
public class Employee {
@NotNull(message = "{employee.id.isNULL}")
private Integer id;
@Length(min=4,max=12,message="{employee.name.error}")
private String name;
@Email(message = "{employee.email.isemail}")
private String email;
1、employee.id.isNULL、employee.name.error和employee.email.isemail:就是读取ValidationMessages.properties中的配置信息。从这里就可以理解该配置文件的意义,防止硬编码。
2.6、捕获校验错误信息
@Controller
public class TestValidatorController {
@RequestMapping(value = "addEmployee",method = RequestMethod.POST)
public String addEmployee(@Valid @ModelAttribute Employee employee,
BindingResult result ,Model model) {
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError objectError : allErrors) {
// 输出错误信息
System.out.println(objectError.getDefaultMessage());
}
// 将错误信息传到页面
model.addAttribute("allErrors", allErrors);
//可以直接使用model将提交pojo回显到页面
model.addAttribute("employee", employee);
// 出错重新到修改页面
return "error";
}
在需要校验的pojo前边添加@Validated,在需要校验的pojo后边添加BindingResult bindingResult接收校验出错信息
//注意:@Validated和BindingResult bindingResult是配对出现,并且形参顺序是固定的(一前一后)
2.7 在页面测试数据校验
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form:form modelAttribute="employee" action="addEmployee" method="post">
ID:<input type="text" name="id" value=${employee.id}>
<form:errors path="id"></form:errors><br />
姓名:<input type="text" name="name">
<form:errors path="name"></form:errors>
<br />
邮箱:<input type="text" name="email" value=${employee.email}>
<form:errors path="email"></form:errors>
<br />
<input type="submit" value="提交">
</form:form>
2.8在页面展现错误信息
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<!-- 显示错误信息 -->
<c:if test="${allErrors!=null }">
<c:forEach items="${allErrors }" var="error">
${ error.defaultMessage}<br/>
</c:forEach>
</c:if>
测试结果:
只要在Controller 中改为return"原先的页面“