本文转自:http://elf8848.iteye.com/blog/1299587
Spring 基于注释的校验机制:
1)支持JSR303 Bean Validation定义的校验规范。
2) 支持Spring框架定义的Validator接口定义的校验。
表单:user.jsp
注册用户包含三项信息: 用户名,密码,邮箱。
<%@ page language="java" contentType="text/html; charset=UTF-8"%>与上述form中对应的user对象如下:
public class User {
private String userName;
private String password;
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();
}
}
在这里不讨论前端JS的校验,只说明SpringMVC中的后台校验机制。
校验方式一: JSR303 Bean Validation
Spring3.1后增加的了对JSR303 Bean Validation规范的支持,不仅可以对Spring的 MVC进行校验,而且也可以对Hibernate的存储对象(POJO)进行校验,是一个通用的校验框架。
环境准备:
A) 导入Hibernate-Validator
要使用JSR303 校验框架, 需要加入框架的具体实现Hibernate-Validator, 在http://mvnrepository.com/上下载最新的Hibernate-Validator ,
当前版本为5.2.4 Final版。
在/WEB-INF/lib中导入 hibernate-validator-5.2.4.Final.jar, hibernate-validator-annotation-processor-5.2.4.Final.jar,
导入它的lib/required目录下内容slf4j-api-1.7.2.jar, validation-api-1.1.0.Final.jar;
B) 配置Spring对JSR 303 的支持。
在你的springMVC的配置文件中增加如下配置:配置对JSR303的支持,包括自动查找Hibernate-Validator的实现等工作。
<mvc:annotation-driven />
校验属性的Constraints的设定
该步骤就是对校验对象的属性使用JSR303原生的注解Constraints对需要校验的属性进行约束限定。
在JSR303中已经定义的Constraint如下:
空检查
@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=) 验证字符串的长度是否在给定的范围之内,包含两端
日期检查
@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();
}
}
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
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", "邮箱格式错误");
}
}
}
设置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="*" />来显示。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。