zoukankan      html  css  js  c++  java
  • [译]SpringMVC自定义验证注解(SpringMVC custom validation annotations)

    在基于SpringMVC框架的开发中,我们经常要对用户提交的字段进行合法性验证,比如整数类型的字段有个范围约束,我们会用@Range(min=1, max=4)。在实际应用开发中,我们经常碰到一些自己业务的场景要自定义一些验证规则,而这是标准的JSR-303Hibernate Validation所不具备的,所以我们就要根据JSR-303的规范来扩展我们自定义的验证规则注释.

    假设我们现在有个接口要接收一个手机的字段, 它的约束规则是13位数字字符. 我们可以通过正则表达式完成: ^d{13}$来验证. 下面是个javabean代码:

    public class Person{
        @Phone
        private String phone;
    }
    

    我们再来看下@Phone的代码.

    @Documented
    @Constraint(validatedBy = PhoneConstraintValidator.class)
    @Target( { ElementType.METHOD, ElementType.FIELD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Phone {
    	String message() default "{Phone}";
    	Class<?>[] groups() default {};
    	Class<? extends Payload>[] payload() default {};
    }
    

    这个注解类看起来复杂, 其实不然. 因为这基本上每个扩展验证注解都必需定义的三个方法, 是规范定义的, 所以我们可以像个模板一样copy过来改下. 这里要注意的是这个message方法, 定义了如果验证出错时要显示的消息内容. 对于消息格式和规范, 可以使用标准的Spring Message Resource Bindle来, 可以参考这篇. 现在定义了注解, 正如你所料, 我们要定义下具体的业务规则:

    public class PhoneConstraintValidator implements ConstraintValidator<Phone, String> {
    
    	@Override
    	public void initialize(Phone phone) { }
    
    	@Override
    	public boolean isValid(String phoneField, ConstraintValidatorContext cxt) {
    		if(phoneField == null) {
    			return false;
    		}
    		return phoneField.matches("^d{13}$");
    	}
    }
    

    所有验证规则方法类都要实现ConstraintValidator<V,F>这个接口, 里面第一个方法initialize的参数是所关联的注解对象, 所以这个方法里可以取出使用注解的地方传进来的值, 后面一个例子会讲到这一点. 第二个最核心的方法isValid第一个参数就是我们要验证的字段值, 大家看下上面的代码就知道怎样使用了.

    下面我们来看第二种形式的注解. 假如我们对用户的生日字段进行验证, 限制只满足1989年出生的人。 如下:

    public class Person {
    	@Year(1989)
    	private Date birthday;
    
        // getters setters ...
    
    }
    

    现在自定义验证注解Year有要传入一个参数, 用默认的value方法接收:

    @Documented
    @Constraint(validatedBy = YearConstraintValidator.class)
    @Target( { ElementType.METHOD, ElementType.FIELD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Year {
    
    	int value();
    
    	String message() default "{Year}";
    
    	Class<?>[] groups() default {};
    
    	Class<? extends Payload>[] payload() default {};
    
    }
    

    还是要上面的一样, 要定义一个规则约束描述类:

    public class YearConstraintValidator implements ConstraintValidator<Year, Date> {
    
    	private int annotationYear;
    
    	@Override
    	public void initialize(Year year) {
    		this.annotationYear = year.value();
    	}
    
    	@Override
    	public boolean isValid(Date target, ConstraintValidatorContext cxt) {
    		if(target == null) {
    			return true;
    		}
    		Calendar c = Calendar.getInstance();
    		c.setTime(target);
    		int fieldYear = c.get(Calendar.YEAR);
    		return fieldYear == annotationYear;
    	}
    
    }
    

    可以看到initiallize方法中可以接收关联的注解Year, 这里可以取出里面的参数信息用于约束规则方法调用.

    原文: http://www.javacodegeeks.com/2013/07/spring-mvc-custom-validation-annotations.html

  • 相关阅读:
    oracle 复制表结构 复制表数据 sql 语句
    Linux rsync实现断点续传
    qt实现一个简单的计算器
    python脚本0b文件处理
    同步和互斥
    python中的randint,引入模块
    python中常见的三种句型if,while,for
    python中的变量,运算符
    python安装与使用
    常见dos命令总结
  • 原文地址:https://www.cnblogs.com/jcli/p/4050447.html
Copyright © 2011-2022 走看看