前言:常用的validation
注解可能不太满足实际使用场景,基于它可以拓展自己的注解校验。
示例:自定义正则校验注解
- @Constraint(validatedBy={IPattern.Validator.class}) 指定当前注解校验器(实现
ConstraintValidator
校验器的类)
- @ConstraintComposition(CompositionType.AND) 引入外部注解时的规则(OR、AND、ALL_FALSE)
- @ReportAsSingleViolation 引入外部注解时,外部注解的错误信息会使用当前注解的错误信息, 否则使用自己的错误信息
- @Repeatable 是否支持重复注解, 在一个字段上多次使用(分组不同)
- @OverridesAttribute 覆盖注解属性值(要指定被覆盖注解的某个属性名称)
一、自定义正则校验注解,替代javax.validation.constraints.Pattern
注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import org.apache.commons.lang3.StringUtils; import org.hibernate.validator.constraints.CompositionType; import org.hibernate.validator.constraints.ConstraintComposition; import org.hibernate.validator.constraints.Length;
import javax.validation.*; import java.lang.annotation.*;
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = IPattern.Validator.class) @Repeatable(IPattern.List.class) @ConstraintComposition(CompositionType.AND) @ReportAsSingleViolation @Length public @interface IPattern { String message() default "IPattern格式错误";
Class<?>[] groups() default {};
Class<?>[] payload() default {};
RegexEnum regexp() default RegexEnum.NONE;
@OverridesAttribute(constraint = Length.class, name = "min") int min() default 0;
@OverridesAttribute(constraint = Length.class, name = "max") int max() default Integer.MAX_VALUE;
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @interface List { IPattern[] value(); }
class Validator implements ConstraintValidator<IPattern, String> { private RegexEnum regex;
@Override public void initialize(IPattern constraintAnnotation) { regex = constraintAnnotation.regexp(); }
@Override public boolean isValid(String value, ConstraintValidatorContext context) { if (StringUtils.isBlank(value)) { return true; } return value.matches(regex.getRegex()); } } }
|
二、定义正则枚举类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| public enum RegexEnum {
NONE(".*"),
NAME("^[\u4e00-\u9fa5a-zA-z ]*$"),
PASSWORD("[0-9a-zA-z-_]{8,16}"),
PHONE("^\\d{3}-\\d{8}$|^\\d{4}-\\d{7}$|^(?:(?:\\+|00)86)?1\\d{10}$"),
EMAIL("^([A-Za-z0-9_\\-.\\u4e00-\\u9fa5])+@([A-Za-z0-9_\\-.])+\\.([A-Za-z]{2,8})$"),
URL("/^(((ht|f)tps?):\\/\\/)?[\\w-]+(\\.[\\w-]+)+([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?$/"),
ID_CARD("(^\\d{8}(0\\d|10|11|12)([0-2]\\d|30|31)\\d{3}$)|(^\\d{6}(18|19|20)\\d{2}(0[1-9]|10|11|12)([0-2]\\d|30|31)\\d{3}(\\d|X|x)$)"),
SSC("^[0-9A-Z]{15}$|^[0-9A-Z]{18}$|^[0-9A-Z]{20}$"),
NUMBER("^[0-9]*$"),
CHARS_EN("^[a-zA-z0-9]*$"),
SPECIAL_CHARS_EN("^[a-zA-z0-9-_]*$"),
SPECIAL_CHARS_SPACE_EN("^[a-zA-z0-9-_ ]*$"),
CHARS_CN("^[\u4e00-\u9fa5a-zA-z0-9]*$"),
SPECIAL_CHARS_CN("^[\u4e00-\u9fa5a-zA-z0-9-_]*$"),
SPECIAL_CHARS_SPACE_CN("^[\u4e00-\u9fa5a-zA-z0-9-_ ]*$"),
; private final String regex;
RegexEnum(String regex) { this.regex = regex; }
public String getRegex() { return regex; } }
|
三、使用注解
原来怎么用,这个就怎么用
1 2 3 4 5
| public class UserDTO { @IPattern(regexp = RegexEnum.SPECIAL_CHARS_CN, max = 30, message = "用户名称格式不正确") private String name; }
|