b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,本节主要学习springmvc实现控制层添加校验。
Spring3支持JSR-303验证框架,JSR-303 是JAVA EE 6 中的一项子规范,叫做BeanValidation,官方参考实现是Hibernate Validator(与Hibernate ORM 没有关系),JSR 303 用于对Java Bean 中的字段的值进行验证。
在商品信息修改提交时对商品信息内容进行校验,例如商品名称必须输入,价格合法性校验。
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="messageSource" />
bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:CustomValidationMessagesvalue>
list>
property>
<property name="fileEncodings"value="utf-8" />
<property name="cacheSeconds"value="120" />
bean>
<mvc:annotation-driven validator="validator"> mvc:annotation-driven>
<bean id="customBinder"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator"ref="validator" />
bean>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer"ref="customBinder">property>
bean>
public class Items {
private Integer id;
@Size(min=1,max=30,message="{item.name.length.error}")
private String name;
@NotEmpty(message="{pic.is.null}")
private String pic;
item.name.length.error=商品名称在1到30个字符之间
pic.is.null=请上传图片
如果在eclipse中编辑properties文件无法看到中文则参考“Eclipse开发环境配置-indigo.docx”添加propedit插件。
修改Controller方法:
// 商品修改提交
@RequestMapping("/editItemSubmit")
public String editItemSubmit(@Validated @ModelAttribute("item") Itemsitems,BindingResult result,
@RequestParam("pictureFile") MultipartFile[] pictureFile,Model model)
throws Exception {
//如果存在校验错误则转到商品修改页面
if (result.hasErrors()) {
List
for(ObjectError objectError:errors){
System.out.println(objectError.getCode());
System.out.println(objectError.getDefaultMessage());
}
return "item/editItem";
}
注意:添加@Validated表示在对items参数绑定时进行校验,校验信息写入BindingResult中,在要校验的pojo后边添加BingdingResult,一个BindingResult对应一个pojo,且BingdingResult放在pojo的后边。
商品修改页面显示错误信息:
页头:
<%@ page language="java"contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"
<%@ taglib prefix="spring"uri="http://www.springframework.org/tags"%>
在需要显示错误信息地方:
<spring:hasBindErrors name="item">
<c:forEach items="${errors.allErrors}"var="error">
${error.defaultMessage}<br/>
c:forEach>
spring:hasBindErrors>
说明:
上边的方法也可以改为:
在controller方法中将error通过model放在request域,在页面上显示错误信息:
controller方法:
if(bindingResult.hasErrors()){
model.addAttribute("errors", bindingResult);
}
页面:
<c:forEach items="${errors.allErrors}"var="error">
${error.defaultMessage }<br/>
c:forEach>
如果两处校验使用同一个Items类则可以设定校验分组,通过分组校验可以对每处的校验个性化。
需求:商品修改提交只校验商品名称长度
定义分组:
分组就是一个标识,这里定义一个接口:
public interface ValidGroup1 {
}
public interface ValidGroup2 {
}
指定分组校验:
public class Items {
private Integer id;
//这里指定分组ValidGroup1,此@Size校验只适用ValidGroup1校验
@Size(min=1,max=30,message="{item.name.length.error}",groups={ValidGroup1.class})
private String name;
// 商品修改提交
@RequestMapping("/editItemSubmit")
public String editItemSubmit(@Validated(value={ValidGroup1.class}) @ModelAttribute("item") Items items,BindingResultresult,
@RequestParam("pictureFile") MultipartFile[] pictureFile,Model model)
throws Exception {
在@Validated中添加value={ValidGroup1.class}表示商品修改使用了ValidGroup1分组校验规则,也可以指定多个分组中间用逗号分隔,
@Validated(value={ValidGroup1.class,ValidGroup2.class })
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内