自定义参数校验注解

9 篇文章 0 订阅

注解定义

Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。
Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java虚拟机可以保留注解内容,在运行时可以获取到注解内容。

元注解

  • @Target - 标记注解注释哪种 Java 成员。
  • @Retention - 标记注解存储方式
  • @Documented - 标记注解是否包含在Javadoc用户文档中。
  • @Inherited - 标记注解可以被继承

1.@Target

限制注解的注释类型,类型在 ElementType 中

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,
    /** Field declaration (includes enum constants) */
    FIELD,
    /** Method declaration */
    METHOD,
    /** Formal parameter declaration */
    PARAMETER,
    /** Constructor declaration */
    CONSTRUCTOR,
    /** Local variable declaration */
    LOCAL_VARIABLE,
    /** Annotation type declaration */
    ANNOTATION_TYPE,
    /** Package declaration */
    PACKAGE,
    /** Type parameter declaration*/
    TYPE_PARAMETER,
    /** Use of a type*/
    TYPE_USE
}

2.@Retention

规定注解的存储方式,要保留多久,参数在 RetentionPolicy 中

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 保留在源代码中,编译时忽略
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 保留在字节码中,VM 运行时忽略
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     * 运行 VM 时保留,因此可以通过反射进行读取
     */
    RUNTIME
}

模拟场景

校验请求参数,参数为手机号,校验其格式的正确与否

1.自定义注解体

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;

/**
 * 自定义手机号码校验注解
 *
 * @author YoonaLt
 * @date 2019-10-14
 */
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AbstractInterfaceRealize.class)  // 约束类
public @interface MyAnnotation {
    String message() default "数据格式有误";

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

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

注解内的     Class<?>[] groups() default {};     Class<? extends Payload>[] payload() default  {}; 不要忘记,且名称固定,否则使用时报错

javax.validation.ConstraintDefinitionException: HV000074: com.yoona.MyAnnotation contains Constraint annotation, but does not contain a payload(或者为groups) parameter.

2.编写注解验证器

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

/**
 * 注解验证器
 *
 * @author YoonaLt
 * @date 2019-10-14
 */
public abstract class AbstractInterfaceRealizee implements ConstraintValidator<MyAnnotation, String> {
    // ConstraintValidator<MyAnnotation, String> String为要注释的数据的类型
    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        // 号码长度
        int len = 11;
        if (value == null || "".equals(value) || value.length() != len) {
            return false;
        }
        // 测试的校验规则
        String regex = "^1[3|4|5|7|8][0-9]\\d{4,8}$";
        return value.matches(regex);
    }
}

3.测试

import com.yoona.custom.MyAnnotation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author YoonaLt
 * @date 2019-10-14
 */
@Validated  // 这里使用这个注解使我们自定义的注解生效
@RestController
@RequestMapping(value = "test")
public class TestAnnotation {

    @GetMapping(value = "test")
    public void myTest(@MyAnnotation String number) {
    }
}

当参数 number 不符合验证器内的规定时,我们可以看到报错信息

javax.validation.ConstraintViolationException: myTest.number: 数据格式有误
	at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:116)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
...........................................

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值