zoukankan      html  css  js  c++  java
  • Java数据校验(Bean Validation / JSR303)

    文档: http://beanvalidation.org/1.1/spec/
    API : http://docs.jboss.org/hibernate/beanvalidation/spec/1.1/api/

    http://blog.sina.com.cn/s/blog_a3d2fd2d0101hyu7.html
    http://haohaoxuexi.iteye.com/blog/1812584

    JSR303是JAVA EE6中的子规范。用于对Java Bean的字段值进行校验,确保输入进来的数据在语义上是正确的,使验证逻辑从业务代码中脱离出来。JSR303是运行时数据验证框架,验证之后验证的错误信息会马上返回。有两个版本JSR303(BeanValidation1.0)和JSR349(BeanValidation1.1)。

    javax.validation:validation-api:jar:1.1.0.Final
    实现版本:

    • org.hibernate:hibernate-validator:5.2.4.Final
    • org.apache.bval:bval-jsr303:0.5
    • jersery

    注解

    @NotNull | 引用类型 | 注解元素必须非空
    @Null | 引用类型 |元素为空
    @Digits | byte,short,int,long及其包装器,BigDecimal,BigInteger,String| 验证数字是否合法。属性:integer(整数部分), fraction(小数部分)
    @Future/@Past| java.util.Date, java.util.Calendar | 是否在当前时间之后或之前
    @Max/@Min | byte,short,int,long及其包装器,BigDecimal,BigInteger | 验证值是否小于等于最大指定整数值或大于等于最小指定整数值
    @Pattern | String |验证字符串是否匹配指定的正则表达式。属性:regexp(正则), flags(选项,Pattern.Flag值)
    @Size | String, Collection, Map, 数组 | 验证元素大小是否在指定范围内。属性:max(最大长度), min(最小长度), message(提示,默认为{constraint.size})
    @DecimalMax/@DecimalMin | byte,short,int,long及其包装器,BigDecimal,BigInteger,String | 验证值是否小于等于最大指定小数值或大于等于最小指定小数值
    @Valid | |验证值是否需要递归调用

    @Null
    @NotNull
    @AssertFalse
    @AssertTrue
    @DecimalMax(value) 不大于value的数值
    @DecimalMin(value) 不小于value的数值
    @Digits(integer,fraction) 整数部分不超过integer,小数部分不超过fraction
    @Future 将来的日期
    @Past 过去的日期
    @Max(value) 不大于value的数值
    @Min(value) 不小于value的数值
    @Pattern(value) 满足指定正则表达式
    @Size(max,min) 长度在min到max之间

    定义自己的约束类型

    定义注解,message、groups和payload三个属性是必须定义的。

    @Target({ElementType.FIELD, ElementType.METHOD})  
    @Retention(RetentionPolicy.RUNTIME)  
    @Constraint(validatedBy=MoneyValidator.class)  //用于限制的注解,验证类为MoneyValidator
    public @interface Money {    
        String message() default"不是金额形式";  
        Class<?>[] groups() default {};  
        Class<? extends Payload>[] payload() default {};  
    }  
    

    定义验证类

    public class MoneyValidator implements ConstraintValidator<Money, Double> {  
        private String moneyReg = "^\d+(\.\d{1,2})?$";//表示金额的正则表达式  
        private Pattern moneyPattern = Pattern.compile(moneyReg);  
        public void initialize(Money money) {  
           // TODO Auto-generated method stub  
        }  
        public boolean isValid(Double value, ConstraintValidatorContext arg1) {  
           // TODO Auto-generated method stub  
           if (value == null)  
               return true;  
           return moneyPattern.matcher(value.toString()).matches();  
        }  
    }  
    

    ConstraintValidator使用了泛型,有两个类型参数。第一个类型是对应的initialize方法的参数类型(约束注解类型),第二个类型是对应的isValid方法的第一个参数类型。

    Hibernate Validator

    Hibernate Validator附加的constraint(hibernate-validator和validation-api)

    @Email 被注释的元素必须是电子邮箱地址
    @Length 字符串的大小必须在指定的范围内
    @NotEmpty 被注释的字符串的必须非空
    @Range 被注释的元素必须在合适的范围内

    验证对象类型

    字段约束

    当约束被定义在字段上的时候, 这个字段的值是通过字段访问策略来获取并验证的. 也就是说Bean Validation的实现者会直接访问这个实例变量而不会调用属性的访问器(getter) 即使这个方法存在。静态字段或者属性是不会被校验的

    属性约束

    必须遵守JavaBeans规范,且定义在getter上,不能定义在setter上

    类约束

    约束继承

    验证子类时所有基类中的约束也都会被使用

    对象图

    @Valid注解类中的对象属性

    Validator接口

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator =  factory.getValidator();
    ... = validator.validate(obj);      //对一个给定的实体对象中定义的所有约束进行校验
    ... = validator.validateProperty(); //通过validateProperty()可以对一个给定实体对象的单个属性进行校验,需要符合JavaBean命名规范
    ... = validator.validateValue();    //校验如果把一个特定的值赋给一个类的某一个属性的话,是否会违反此类中定义的约束条件
    
    
    ####约束提示信息
    * 可直接通过注解的message属性设置
    * 通过message提供模板,ValidationMessages.properties中定义
    
    
    
    
    
    Spring MVC Validator接口
    --------------------
    定义Validator。 Supports方法用于判断当前的Validator实现类是否支持校验当前需要校验的实体类,只有当supports方法的返回结果为true的时候,该Validator接口实现类的validate方法才会被调用来对当前需要校验的实体类进行校验。
    ```java
    public class UserValidator implements Validator {  
        public boolean supports(Class<?> clazz) {  
           return User.class.equals(clazz);  
        }  
        public void validate(Object obj, Errors errors) {  
           ValidationUtils.rejectIfEmpty(errors, "username", null, "Username is empty.");  
           User user = (User) obj;  
           if (null == user.getPassword() || "".equals(user.getPassword()))  
               errors.rejectValue("password", null, "Password is empty.");  
        }  
    }  
    

    使用Validator进行验证。在SpringMVC中我们可以使用DataBinder来设定当前Controller需要使用的Validator。

    @Controller  
    public class UserController {  
        @InitBinder  
        public void initBinder(DataBinder binder) {  
           binder.setValidator(new UserValidator());  
        }  
        @RequestMapping("login")  
        public String login(@Valid User user, BindingResult result) {  
           if (result.hasErrors())  
               return "redirect:user/login";  
           return "redirect:/";  
        }   
    }  
    

    必须使用@Valid标注我们需要校验的参数user,否则Spring不会对它进行校验。另外我们的处理器方法必须给定包含Errors的参数,这可以是Errors本身,也可以是它的子类BindingResult,使用了Errors参数就是告诉Spring关于表单对象数据校验的错误将由我们自己来处理,否则Spring会直接抛出异常,而且这个参数是必须紧挨着@Valid参数的,即必须紧挨着需要校验的参数,这就意味着我们有多少个@Valid参数就需要有多少个对应的Errors参数,它们是一一对应的。

    如果我们希望一个Validator对所有的Controller都起作用的话,我们可以通过WebBindingInitializer的initBinder方法来设定了。另外,在SpringMVC的配置文件中通过mvc:annotation-driven的validator属性也可以指定全局的Validator。

    <mvc:annotation-driven validator="userValidator"/>

    Spring可以通过@Resource或@AutoWired注解向ConstraintValidator注入对象。

  • 相关阅读:
    Tuning 14 Using Oracle Data Storage Structures Efficiently
    Tuning 13 Using oracle blocks Efficiently
    Tuning 12 manage statistics
    Tuning SQL 11
    【TYVJ】1307 联络员(最小生成树)
    【wikioi】1022 覆盖(匈牙利)
    【TYVJ】1338 QQ农场(最大流+最大权闭合图)
    【BZOJ】3038: 上帝造题的七分钟2(线段树+暴力)
    【BZOJ】1087: [SCOI2005]互不侵犯King(状压dp)
    【BZOJ】1041: [HAOI2008]圆上的整点(几何)
  • 原文地址:https://www.cnblogs.com/pixy/p/5306567.html
Copyright © 2011-2022 走看看