发张美女图镇楼,接下来说说一下SpringMVC中的校验。
使用注解
一、准备校验时使用的JAR
说明:
validation-api-1.0.0.GA.jar是JDK的接口;
hibernate-validator-4.2.0.Final.jar是对上述接口的实现。
编写需要校验的bean
import org.hibernate.validator.constraints.NotNull; ... @NotNull(message="名字不能为空") private String userName; @Max(value=120,message="年龄最大不能查过120") private int age; @Email(message="邮箱格式错误") private String email;
三、校验方法
@RequestMapping("/login") public String testValid(@Valid User user, BindingResult result){ if (result.hasErrors()){ logger.warn(String.format("入参校验未通过,[ %s ]", result.getAllErrors().toString())); throw new BusinessException(ErrCodeConfig.CODE_ILLPARAMERROR, "参数校验失败"); } return "test"; }
备注:这里一个@Valid的参数后必须紧挨着一个BindingResult 参数,否则spring会在校验不通过时直接抛出异常
增加显示验证结果的jsp如下
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <html> <head> <title>Reservation Form</title> <style> .error { color: #ff0000; font-weight: bold; } </style> </head> <body> <form:form method="post" modelAttribute="vm"> <form:errors path="*" cssClass="error" /> <table> <tr> <td>Name</td> <td> <form:input path="userName" /> </td> <td> <form:errors path="userName" cssClass="error" /> </td> </tr> <tr> <td>email</td> <td> <form:input path="email" /> </td> <td> <form:errors path="email" cssClass="error" /> </td> </tr> <tr> <td colspan="3"> <input type="submit" /> </td> </tr> </table> </form:form> </body> </html>
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=) 检查数字是否介于min和max之间. @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=)
@Valid是使用hibernate validation的时候使用
@Validated 是只用spring Validator 校验机制使用
参考文章:http://blog.csdn.net/walkerjong/article/details/7210727
校验方式二: 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="*" />来显示。