MVC 表单验证

表单:

用户注册页面: 名称:user.jsp
注册用户包含三项信息: 用户名,密码,邮箱。

[html] view plain copy
  1. < %@page language = "java" contentType = "text/html;charset=UTF-8" % >
  2. < %@taglib prefix = "sf" uri = "http://www.springframework.org/tags/form" % >
  3. <!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
  4. < html >
  5. < head >
  6. < meta http-equiv = "Content-Type" content = "text/html;charset=UTF-8" >
  7. < title > UserRegisterPage </ title >
  8. < style type = "text/css" >
  9. .error{
  10. color:red;
  11. }
  12. </ style >
  13. </ head >
  14. < body >
  15. < %--
  16. 这里指定页面绑定的对象modelAttribute.之前很困惑,
  17. 为什么< form > 上最重要的 < form action = "someAction.do" > 属性没了呢?
  18. 后来发现,其实在controller中的方法以及指定了地址到method的对应关系,
  19. < form > 里的action属性就可以退休了。
  20. --%>
  21. < sf:form method = "post" modelAttribute = "user" >
  22. < p > 用户注册页面: </ p >
  23. < table width = "60%" align = "center" >
  24. < colgroup >
  25. < col width = "10%" align = "right" />
  26. < col />
  27. </ colgroup >
  28. < tr >
  29. < th > 用户名: </ th >
  30. < td >
  31. < sf:input path = "userName" />
  32. < small > lengthofuserNameisnotmorethan20. </ small > < br />
  33. < %--显示关于userName属性相关的错误信息。--% >
  34. < sf:errors path = "userName" cssClass = "error" />
  35. </ td >
  36. </ tr >
  37. < tr >
  38. < th > 密码: </ th >
  39. < td >
  40. < sf:password path = "password" />
  41. < small > lengthofpasswordisnotlessthan6. </ small > < br />
  42. < sf:errors path = "password" cssClass = "error" />
  43. </ td >
  44. </ tr >
  45. < tr >
  46. < th > 邮箱: </ th >
  47. < td >
  48. < sf:input path = "email" />
  49. < small > formatshouldconfirmtogeneralstandard. </ small > < br />
  50. < sf:errors path = "email" cssClass = "error" />
  51. </ td >
  52. </ tr >
  53. < tr >
  54. < td colspan = "2" align = "center" >
  55. < input type = "submit" value = "注册" />
  56. </ td >
  57. </ tr >
  58. </ table >
  59. </ sf:form >
  60. </ body >
  61. </ 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配置文件中,使用标签:

[html] view plain copy
  1. < 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对象如下:

[java] view plain copy
  1. package org.study.domain;
  2. import javax.validation.constraints.Pattern;
  3. import javax.validation.constraints.Size;
  4. import org.study.validation.annotation.NotEmpty;
  5. public class User{
  6. @Size (min= 3 ,max= 20 ,message= "用户名长度只能在3-20之间" )
  7. private StringuserName;
  8. @Size (min= 6 ,max= 20 ,message= "密码长度只能在6-20之间" )
  9. private Stringpassword;
  10. @Pattern (regexp= "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" ,message= "邮件格式错误" )
  11. private Stringemail;
  12. public StringgetUserName(){
  13. return userName;
  14. }
  15. public void setUserName(StringuserName){
  16. this .userName=userName;
  17. }
  18. public StringgetPassword(){
  19. return password;
  20. }
  21. public void setPassword(Stringpassword){
  22. this .password=password;
  23. }
  24. public StringgetEmail(){
  25. return email;
  26. }
  27. public void setEmail(Stringemail){
  28. this .email=email;
  29. }
  30. public StringtoString(){
  31. StringBuildersb=new StringBuilder();
  32. sb.append(getClass()).append("[" )
  33. .append("userName=" ).append(userName).append( "," )
  34. .append("password=" ).append(password).append( "," )
  35. .append("email=" ).append(email).append( "]" );
  36. return sb.toString();
  37. }
  38. }


2) Validate的触发
在需要校验的对象前增加 @Valid 注解 (该注解位于javax.validation包中)来触发校验。示例如下:

[java] view plain copy
  1. /**
  2. *处理提交的用户注册信息。
  3. *@parammodel
  4. *@return
  5. */
  6. @RequestMapping (method=RequestMethod.POST)
  7. public StringdoRegister( @Valid Useruser,BindingResultresult){
  8. if (logger.isDebugEnabled()){
  9. logger.debug("processurl[/user],method[post]in" +getClass());
  10. }
  11. //校验没有通过
  12. if (result.hasErrors()){
  13. return "user" ;
  14. }
  15. if (user!= null ){
  16. userService.saveUser(user);
  17. }
  18. return "user" ;
  19. }


这样就可以完成针对输入数据User对象的校验了, 校验结果任然保存在BindingResult对象中。

校验方式二: Spring Validator

1)Validator接口的实现:

Spring框架的Validator接口定义,

[java] view plain copy
  1. package org.springframework.validation;
  2. public interface Validator{
  3. boolean supports(Class<?>clazz);
  4. void validate(Objecttarget,Errorserrors);
  5. }

要使用它进行校验必须实现该接口。实现Validator接口的代码如下:

[java] view plain copy
  1. package org.study.validation.validator;
  2. import org.springframework.validation.Errors;
  3. import org.springframework.validation.ValidationUtils;
  4. import org.springframework.validation.Validator;
  5. import org.study.domain.User;
  6. public class UserValidator implements Validator{
  7. @Override
  8. public boolean supports(Class<?>clazz){
  9. return clazz.equals(User. class );
  10. }
  11. @Override
  12. public void validate(Objecttarget,Errorserrors){
  13. ValidationUtils.rejectIfEmpty(errors,"userName" , "user.userName.required" , "用户名不能为空" );
  14. ValidationUtils.rejectIfEmpty(errors,"password" , "user.password.required" , "密码不能为空" );
  15. ValidationUtils.rejectIfEmpty(errors,"email" , "user.email.required" , "邮箱不能为空" );
  16. Useruser=(User)target;
  17. int length=user.getUserName().length();
  18. if (length> 20 ){
  19. errors.rejectValue("userName" , "user.userName.too_long" , "用户名不能超过{20}个字符" );
  20. }
  21. length=user.getPassword().length();
  22. if (length< 6 ){
  23. errors.rejectValue("password" , "user.password.too_short" , "密码太短,不能少于{6}个字符" );
  24. }else if (length> 20 ){
  25. errors.rejectValue("password" , "user.password.too_long" , "密码太长,不能长于{20}个字符" );
  26. }
  27. int index=user.getEmail().indexOf( "@" );
  28. if (index==- 1 ){
  29. errors.rejectValue("email" , "user.email.invalid_email" , "邮箱格式错误" );
  30. }
  31. }
  32. }


2) 设置Validator,并触发校验。
在我们的Controller中需要使用父类已有的方法来为DataBinder对象指定Validator, protected initBinder(WebDataBinder binder); 代码如下:

[java] view plain copy
  1. @InitBinder
  2. protected void initBinder(WebDataBinderbinder){
  3. binder.setValidator(new UserValidator());
  4. }


为binder对象指定好Validator校验对象后,下面一步的就是在需要校验的时候触发validate方法,该触发步骤是通过 @Validated 注解(该注解是Spring框架定义的)实现的。

[java] view plain copy
  1. /**
  2. *处理提交的用户注册信息。
  3. *@parammodel
  4. *@return
  5. */
  6. @RequestMapping (method=RequestMethod.POST)
  7. public StringdoRegister( @Validated Useruser,BindingResultresult){
  8. if (logger.isDebugEnabled()){
  9. logger.debug("processurl[/user],method[post]in" +getClass());
  10. }
  11. //校验没有通过
  12. if (result.hasErrors()){
  13. return "user" ;
  14. }
  15. if (user!= null ){
  16. userService.saveUser(user);
  17. }
  18. return "user" ;
  19. }


至此,从页面提交的User对象可以通过我们实现的UserValidator类来校验了,校验的结果信息存入BindingResult result对象中。在前台页面可以使用spring-form的标签<sf:errors path="*" />来显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值