声明式数据验证
spring3开始支持JSR-303验证框架,JSR-303支持XML风格的和注解风格的验证,接下来我们首先看一下如何和spring集成
1、需要导入如下jar包
validation-api-1.0.0.GA.jar(标准接口)
hibernate-validator-4.3.0.Final.jar(标准的实现)
jboss-logging-3.1.0.CR2.jar(日志依赖的jar)
2、在 Spring配置总添加对JSR-303验证框架的支持
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <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="basename" value="classpath:message" /> <property name="fileEncodings" value="utf-8" /> <property name="cacheSeconds" value="120" /> </bean> <!-- web初始化绑定 --> <bean id="webBindingInitializer" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <!-- 类型转换 <property name="conversionService" ref="conversionService" /> --> <!-- 数据校验 --> <property name="validator" ref="validator" /> </bean>
3、给POJO类添加注解
package hb.base.privilege.model; import java.util.Date; import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; public class Resource { @NotNull(message = "用户名不能为空") private String resid;//资源的唯一标示 @Length(min=5, max=20, message="用户名长度必须在5-20之间") private String resname;//资源的名称 private String commen;//备注 private Date age; public Date getAge() { return age; } public void setAge(Date age) { this.age = age; } public String getResid() { return resid; } public void setResid(String resid) { this.resid = resid; } public String getResname() { return resname; } public void setResname(String resname) { this.resname = resname; } public String getCommen() { return commen; } public void setCommen(String commen) { this.commen = commen; } }
备注:如果一个属性有多个限制条件,注解可以累加,即一个属性有多个注解
4、实现controller控制类对应的方法
@RequestMapping(value = "/resourceAddAction", method = { RequestMethod.POST, RequestMethod.GET }) public String addAction(@Valid @ModelAttribute("resource") Resource resource,HttpServletRequest request, BindingResult result, Map map) { System.out.println("fffffffffffffffffff"); if (result.hasErrors()) { List errorList = result.getAllErrors(); Iterator it = errorList.iterator(); while (it.hasNext()) { Object obj = it.next(); System.out.println(obj); } return "privilege/resource/resourceAddView"; // return "privilege/resource/resourceDetailView"; } System.out.println(resource.getResid()); // resourceService.addResource(resource); System.out.println("dddddddddddddddddddddddddddddddddddddd"); map.put("resource", resource); return "privilege/resource/resourceDetailView"; } @RequestMapping(value = "/resourceAddAction1") public String addAction1(@Valid @ModelAttribute("resource") Resource resource, Errors errors) { System.out.println("addAction1"); if (errors.hasErrors()) { List errorList = errors.getAllErrors(); Iterator it = errorList.iterator(); while (it.hasNext()) { Object obj = it.next(); System.out.println(obj); } return "privilege/resource/resourceAddView"; // return "privilege/resource/resourceDetailView"; } return "privilege/resource/resourceAddView"; }
上面定义了两个方法,其中提交的表单都是错误的,校验没有通过,但是/resourceAddAction请求页面会直接报错,BindingResult对象没有办法获取到,没有办法debug调试,但是执行/resourceAddAction1请求能够正常debug调试,
1、第一个请求多了一个HttpServletRequest对象,因为你提交的表单时错误的,校验没有通过,因此没有办法转为Commond,HttpServletRequest对象就没有办法生成,导致代码直接出错。
2、第二个请求就没有HttpServletRequest对象,表单提交错了被校验拦截,然后收集错误,最后遍历展示出来。