自定义校验注解

一般自定义校验注解需要已下三步:

1.编写校验注解 即类似@NotEmpty

2.编写自定义校验的逻辑实体类,这个类必须实现ConstraintValidator这个接口,这样才可以被注解用来校验。

3.编写具体的校验逻辑。

我们可以先观察下@NotEmpty 注解:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.hibernate.validator.constraints;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;

@Documented
@Constraint(
    validatedBy = {}
)
@SupportedValidationTarget({ValidationTarget.ANNOTATED_ELEMENT})
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@ReportAsSingleViolation
@NotNull
@Size(
    min = 1
)
public @interface NotEmpty {
    String message() default "{org.hibernate.validator.constraints.NotEmpty.message}";

    Class[] groups() default {};

    Class[] payload() default {};

    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {
        NotEmpty[] value();
    }
}

我们编写的自定义注解类,也必须有message、groups、payload.

package com.zzidc.web.validator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
 * @Description //TODO
 * @Date 2019/3/29 17:22
 * @Param
 * @return
 **/
//注解是指定当前自定义注解可以使用在哪些地方,这里仅仅让他可以使用在方法上和属性上;
@Target({ElementType.METHOD,ElementType.FIELD})
//指定当前注解保留到运行时;
@Retention(RetentionPolicy.RUNTIME)
//指定了当前注解使用哪个类来进行校验。
@Constraint(validatedBy = IdCardValidator.class) //
public @interface IsIdCard {
    String message();
    // default 关键字 接口中被default修饰的方法,在类实现这个接口时不必必须实现这个方法
    Class[] groups() default { };
    // Class 表示不确定的java类型
    // Class 表示java类型
    // Class 分别代表java键值中的key value
    // Class 代表Element
    Class[] payload() default {};
}

编写校验注解的逻辑类,该类必须实现ConstraintValidator:

package com.zzidc.web.validator;

import com.zzidc.web.service.IdCardValidatorService;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @ClassName IdCardValidator
 * @Description  校验注解的校验逻辑
 * @Date 2019/3/29 17:23
 **/
public class IdCardValidator implements ConstraintValidator{
    @Autowired
    private IdCardValidatorService idCardValidatorService;
    /*
     * @Description 校验前的初始化工作
     * @Date 2019/3/29 17:27
     * @Param [isIdCard]
     * @return void
     **/
    @Override
    public void initialize(IsIdCard isIdCard) {
        String message = isIdCard.message();
        System.out.println("自定义的message信息是:".concat(message));
    }

    /*
     * @Description 具体的校验逻辑
     * @Date 2019/3/29 17:29
     * @Param [s, constraintValidatorContext]
     * @return boolean
     **/
    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        return idCardValidatorService.volid(s);
    }
}

在这里我们将具体校验逻辑抽出来,抽成一个service:

package com.zzidc.web.service;

/**
 * @ClassName IdCardValidatorService
 * @Description TODO
 * @Date 2019/3/29 17:34
 **/
public interface IdCardValidatorService {
    boolean volid(String value);
}
package com.zzidc.web.service.impl;

import com.zzidc.web.service.IdCardValidatorService;
import com.zzidc.web.utils.IdCardUtils;
import org.springframework.stereotype.Service;

/**
 * @ClassName IdCardValidatorServiceImpl
 * @Description TODO
 * @Date 2019/3/29 17:35
 **/
@Service
public class IdCardValidatorServiceImpl implements IdCardValidatorService {
    @Override
    public boolean volid(String value) {
        return IdCardUtils.isValidIdCard(value);
    }
}

工具类:

package com.zzidc.web.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * @ClassName IdCardUtils
 * @Description TODO
 * @Date 2019/3/29 17:37
 **/
public class IdCardUtils {
    public static boolean isValidIdCard(String value){
        String regex = "^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$";
        if (StringUtils.isBlank(value)) {
            return false;
        }
        return value.matches(regex);
    }
}

 

你可能感兴趣的:(java)