表单:
用户注册页面: 名称:user.jsp
注册用户包含三项信息: 用户名,密码,邮箱。
- < %@ page language = "java" contentType = "text/html; charset=UTF-8" % >
- < %@ taglib prefix = "sf" uri = "http://www.springframework.org/tags/form" % >
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- < html >
- < head >
- < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
- < title > User Register Page </ title >
- < style type = "text/css" >
- .error{
- color: red;
- }
- </ style >
- </ head >
- < body >
- < %--
- 这里指定页面绑定的对象 modelAttribute. 之前很困惑,
- 为什么< form > 上最重要的 < form action = "someAction.do" > 属性没了呢?
- 后来发现,其实在controller中的方法以及指定了地址到method的对应关系,
- < form > 里的action属性就可以退休了。
- --%>
- < sf:form method = "post" modelAttribute = "user" >
- < p > 用户注册页面: </ p >
- < table width = "60%" align = "center" >
- < colgroup >
- < col width = "10%" align = "right" />
- < col />
- </ colgroup >
- < tr >
- < th > 用户名: </ th >
- < td >
- < sf:input path = "userName" />
- < small > length of userName is not more than 20. </ small > < br />
- < %-- 显示关于userName属性相关的错误信息。 --% >
- < sf:errors path = "userName" cssClass = "error" />
- </ td >
- </ tr >
- < tr >
- < th > 密码: </ th >
- < td >
- < sf:password path = "password" />
- < small > length of password is not less than 6. </ small > < br />
- < sf:errors path = "password" cssClass = "error" />
- </ td >
- </ tr >
- < tr >
- < th > 邮箱: </ th >
- < td >
- < sf:input path = "email" />
- < small > format should confirm to general standard. </ small > < br />
- < sf:errors path = "email" cssClass = "error" />
- </ td >
- </ tr >
- < tr >
- < td colspan = "2" align = "center" >
- < input type = "submit" value = "注册" />
- </ td >
- </ tr >
- </ table >
- </ sf:form >
- </ body >
- </ html >
校验方式一: JSR303 Bean Validation
在Spring3.1中增加的了对JSR303 Bean Validation规范的支持,不仅可以对Spring的 MVC进行校验,而且也可以对Hibernate的存储对象进行校验。是一个通用的校验框架。
环境准备:
A) 导入Hibernate-Validator
要使用JSR303 校验框架, 需要加入框架的具体实现Hibernate-Validator, 在soureforge上下载最新的Hibernate-Validator , 当前版本为4.2.0 Final版。
在/WEB-INF/lib中导入 hibernate-validator-4.2.0.Final.jar, hibernate-validator-annotation-processor-4.2.0.Final.jar, 导入它的lib/required目录下内容slf4j-api-1.6.1.jar, validation-api-1.0.0.GA.jar;
B) 配置Spring对JSR 303 的支持。
在你的 <servletName>-servlet.xml配置文件中,使用标签:
- < mvc:annotation-driven />
配置对JSR303的支持,包括制动查找Hibernate-Validator的实现等工作。
1) 可用的 JSR303注解
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) Validates that the annotated string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则
数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
@Min 验证 Number 和 String 对象是否大等于指定的值
@Max 验证 Number 和 String 对象是否小等于指定的值
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber信用卡验证
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)
通过上述Constraint约束后的User对象如下:
- package org.study.domain;
- import javax.validation.constraints.Pattern;
- import javax.validation.constraints.Size;
- import org.study.validation.annotation.NotEmpty;
- public class User {
- @Size (min= 3 , max= 20 , message= "用户名长度只能在3-20之间" )
- private String userName;
- @Size (min= 6 , max= 20 , message= "密码长度只能在6-20之间" )
- private String password;
- @Pattern (regexp= "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" , message= "邮件格式错误" )
- private String email;
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this .userName = userName;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this .password = password;
- }
- public String getEmail() {
- return email;
- }
- public void setEmail(String email) {
- this .email = email;
- }
- public String toString(){
- StringBuilder sb = new StringBuilder();
- sb.append(getClass()).append("[" )
- .append("userName=" ).append(userName).append( ", " )
- .append("password=" ).append(password).append( ", " )
- .append("email=" ).append(email).append( "]" );
- return sb.toString();
- }
- }
2) Validate的触发
在需要校验的对象前增加 @Valid 注解 (该注解位于javax.validation包中)来触发校验。示例如下:
- /**
- * 处理提交的用户注册信息。
- * @param model
- * @return
- */
- @RequestMapping (method = RequestMethod.POST)
- public String doRegister( @Valid User user, BindingResult result){
- if (logger.isDebugEnabled()){
- logger.debug("process url[/user], method[post] in " +getClass());
- }
- //校验没有通过
- if (result.hasErrors()){
- return "user" ;
- }
- if (user != null ){
- userService.saveUser(user);
- }
- return "user" ;
- }
这样就可以完成针对输入数据User对象的校验了, 校验结果任然保存在BindingResult对象中。
校验方式二: Spring Validator
1)Validator接口的实现:
Spring框架的Validator接口定义,
- package org.springframework.validation;
- public interface Validator {
- boolean supports(Class<?> clazz);
- void validate(Object target, Errors errors);
- }
要使用它进行校验必须实现该接口。实现Validator接口的代码如下:
- package org.study.validation.validator;
- import org.springframework.validation.Errors;
- import org.springframework.validation.ValidationUtils;
- import org.springframework.validation.Validator;
- import org.study.domain.User;
- public class UserValidator implements Validator {
- @Override
- public boolean supports(Class<?> clazz) {
- return clazz.equals(User. class );
- }
- @Override
- public void validate(Object target, Errors errors) {
- ValidationUtils.rejectIfEmpty(errors, "userName" , "user.userName.required" , "用户名不能为空" );
- ValidationUtils.rejectIfEmpty(errors, "password" , "user.password.required" , "密码不能为空" );
- ValidationUtils.rejectIfEmpty(errors, "email" , "user.email.required" , "邮箱不能为空" );
- User user = (User)target;
- int length = user.getUserName().length();
- if (length> 20 ){
- errors.rejectValue("userName" , "user.userName.too_long" , "用户名不能超过{20}个字符" );
- }
- length = user.getPassword().length();
- if (length < 6 ){
- errors.rejectValue("password" , "user.password.too_short" , "密码太短,不能少于{6}个字符" );
- }else if (length> 20 ){
- errors.rejectValue("password" , "user.password.too_long" , "密码太长,不能长于{20}个字符" );
- }
- int index = user.getEmail().indexOf( "@" );
- if (index == - 1 ){
- errors.rejectValue("email" , "user.email.invalid_email" , "邮箱格式错误" );
- }
- }
- }
2) 设置Validator,并触发校验。
在我们的Controller中需要使用父类已有的方法来为DataBinder对象指定Validator, protected initBinder(WebDataBinder binder); 代码如下:
- @InitBinder
- protected void initBinder(WebDataBinder binder){
- binder.setValidator(new UserValidator());
- }
为binder对象指定好Validator校验对象后,下面一步的就是在需要校验的时候触发validate方法,该触发步骤是通过 @Validated 注解(该注解是Spring框架定义的)实现的。
- /**
- * 处理提交的用户注册信息。
- * @param model
- * @return
- */
- @RequestMapping (method = RequestMethod.POST)
- public String doRegister( @Validated User user, BindingResult result){
- if (logger.isDebugEnabled()){
- logger.debug("process url[/user], method[post] in " +getClass());
- }
- //校验没有通过
- if (result.hasErrors()){
- return "user" ;
- }
- if (user != null ){
- userService.saveUser(user);
- }
- return "user" ;
- }
至此,从页面提交的User对象可以通过我们实现的UserValidator类来校验了,校验的结果信息存入BindingResult result对象中。在前台页面可以使用spring-form的标签<sf:errors path="*" />来显示。