SpringMVC使用JSR-303进行校验@Valid和@Validated

发张美女图镇楼,接下来说说一下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="*" />来显示。

赞(52) 打赏
未经允许不得转载:优客志 » JAVA开发
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏