在web应用中为了保证数据的有效性而对用户提交的表单数据是必需的,而前台客户端的验证例如javascript并不总是那么安全和可靠,这样我们就需要一个健壮的后台验证框架来处理这个问题。好在java发布了JSR-303接口标准,而实现这一标准的有很多供应商,Hibernate Validator验证框架是使用得比较多的。
今天在处理用户提交的身份证号码这个表单域遇到了一个问题,大家知道我们的身份证号码早期版本只有15位,而二代身份证号码都是18位,Hibernate Validator的@Size注解只能处理最少多少位至最多多少位,却不能处理15位或18位这种情况,于是乎,我就想到了需要使用自定义注解validator来解决这个问题。
首先我们需要定义一个Annotation:
@Documented @Constraint(validatedBy = { IDConstraintValidator.class }) @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface IDValidator { String message() default "{id}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
然后定义一个类用来处理具体的验证逻辑:
1 public class IDConstraintValidator implements ConstraintValidator<IDValidator, String> { 2 3 @Override 4 public void initialize(IDValidator idValidator) { 5 6 } 7 8 @Override 9 public boolean isValid(String id, ConstraintValidatorContext ctx) { 10 int length = id.length(); 11 if (isNumeric(id) && (length == 15 || length == 18)) { 12 return true; 13 } 14 return false; 15 } 16 }
最后在pojo类上面应用我的注解:
1 public abstract class Person implements Serializable { 2 3 private static final long serialVersionUID = 1L; 4 5 @IDValidator(message="{person.id.invalid}") 6 private String id; 7 8 private String firstName; 9 10 private String lastName; 11 12 private String gender; 13 14 private int age; 15 16 public String getId() { 17 return id; 18 }
我把错误信息放在资源文件里面,省去页面测试描述,但是我把Controller里面打印的错误信息展示出来了: