美文网首页
validation自定义校验注解

validation自定义校验注解

作者: 求心丶 | 来源:发表于2022-05-21 20:28 被阅读0次
前言

javax.validation 是基于JSR-303标准提供的参数校验规范,使用注解方式实现对参数的校验,极其方便。
比较常用的参数校验注解有:

  • @Null 被注解的元素必须为null
  • @NotNull 被注解的元素必须不为null
  • @AssertTrue 被注解的元素必须为true
  • @AssertFalse 被注解的元素必须为false
  • @Min(value) 被注解的元素必须为数字,其值必须大于等于最小值
  • @Max(value) 被注解的元素必须为数字,其值必须小于等于最小值
  • @Size(max,min) 被注解的元素的大小必须在指定范围内
  • @Past 被注解的元素必须为过去的一个时间
  • @Future 被注解的元素必须为未来的一个时间
  • @Pattern 被注解的元素必须符合指定的正则表达式

hibernate里对validation又做了一些拓展,常用的有以下几个:

  • @Length 校验字符串的长度是否在指定范围内
  • @Range 校验数字的范围
  • @URL 校验url是否合法
实现自定义拓展注解校验手机号码

代码部分如下:

具有required属性的基础校验器

package com.cube.share.base.constraints.validator;

/**
 * @author litb
 * @date 2022/3/21 17:55
 */
public class BaseRequiredValidator {

    protected boolean required;

    public boolean isRequired() {
        return required;
    }

    public void setRequired(boolean required) {
        this.required = required;
    }
}

基于正则校验的基础校验器

package com.cube.share.base.constraints.validator;

import java.util.regex.Pattern;

/**
 * @author litb
 * @date 2022/3/21 17:56
 */
public class BasePatternValidator extends BaseRequiredValidator {

    protected Pattern pattern;

    public Pattern getPattern() {
        return pattern;
    }

    public void setPattern(Pattern pattern) {
        this.pattern = pattern;
    }
}

提供抽象的具有 required 和 pattern两个属性的 校验器

package com.cube.share.base.constraints.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.util.regex.Matcher;

/**
 * @author litb
 * @date 2022/3/21 18:50
 * <p>
 * 提供抽象的具有 required 和 pattern两个属性的 校验器,
 * 子类需要实现{@link AbstractPatternValidator#initialize(Annotation)}
 */
public abstract class AbstractPatternValidator<A extends Annotation> extends BasePatternValidator implements ConstraintValidator<A, String> {

    /**
     * Initializes the validator in preparation for
     * {@link #isValid(String, ConstraintValidatorContext)} calls.
     * The constraint annotation for a given constraint declaration
     * is passed.
     * <p>
     * This method is guaranteed to be called before any use of this instance for
     * validation.
     * <p>
     * The default implementation is a no-op.
     *
     * @param constraintAnnotation annotation instance for a given constraint declaration
     */
    @Override
    public abstract void initialize(A constraintAnnotation);

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (!required && value == null) {
            return true;
        }
        if (value == null) {
            return false;
        }
        Matcher matcher = pattern.matcher(value);
        return matcher.matches();
    }
}

自定义手机号码校验注解

package com.cube.share.base.constraints;

import com.cube.share.base.constraints.validator.MobileValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * @author litb
 * @date 2022/3/16 10:06
 * <p>
 * 校验手机号是否合法
 */
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Repeatable(Mobile.List.class)
@Documented
@Constraint(validatedBy = {MobileValidator.class})
public @interface Mobile {

    String message() default "手机号码不合法";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    /**
     * 是否必须有值
     */
    boolean required() default true;

    /**
     * 号码所在区域
     */
    Region region() default Region.MAINLAND;

    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        Mobile[] value();
    }

    /**
     * 区域
     */
    enum Region {
        /**
         * 大陆 (?:0|86|\+86)?1[3-9]\d{9}
         */
        MAINLAND,
        /**
         * 台湾 (?:0|886|\+886)?(?:|-)09\d{8}
         */
        TW,
        /**
         * 香港 (?:0|852|\+852)?\d{8}
         */
        HK,
        /**
         * 澳门 (?:0|853|\+853)?(?:|-)6\d{7}
         */
        MO
    }
}

自定义注解@Mobile的校验器

package com.cube.share.base.constraints.validator;

import com.cube.share.base.constraints.ConstraintConstants;
import com.cube.share.base.constraints.Mobile;

/**
 * @author litb
 * @date 2022/3/21 17:50
 * <p>
 * 为{@link Mobile}实现的Validator
 */
public class MobileValidator extends AbstractPatternValidator<Mobile> {

    @Override
    public void initialize(Mobile annotation) {
        required = annotation.required();
        Mobile.Region region = annotation.region();
        switch (region) {
            case MAINLAND:
                pattern = ConstraintConstants.MOBILE_MAINLAND_PATTERN;
                break;
            case HK:
                pattern = ConstraintConstants.MOBILE_HK_PATTERN;
                break;
            case MO:
                pattern = ConstraintConstants.MOBILE_MO_PATTERN;
                break;
            case TW:
                pattern = ConstraintConstants.MOBILE_TW_PATTERN;
                break;
            default:
                throw new IllegalArgumentException("unmatched region");
        }
    }

}

自定义注解@Mobile的用法与validation实现的其他注解完全相同,在指定参数加上即可

 /**
     * 手机号,非必填
     */
    @Mobile(required = false)
    private String mobile;

示例代码

相关文章

网友评论

      本文标题:validation自定义校验注解

      本文链接:https://www.haomeiwen.com/subject/fnthprtx.html