自定义参数校验注解

自定义参数注解

背景

今天在解决测试漏洞的时候需要对各个类的参数添加参数校验,其中想通过正则表达式来添加特殊字符的拦截,因为有很多的类都需要,一个一个加会比较麻烦,所以想到自己定义一个注解会方便一些,说干就干,下面式自定义注解的大概流程。

自定义规则注解流程

规则匹配类定义

首先需要定义一个规则类,这个类继承ConstraintValidator类,该类需要两个参数,分别为后续定义的注解类,这里定义的注解类为SpecialMatch,以及校验参数的类型,这里使用String类型为例

package com.xasj.common.annotation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 莫须有
 * @Date 2022/10/11 16:18
 * @Description
 */
public class SpecialCharacterMatch implements ConstraintValidator<SpecialMatch, String> {
    private static final Pattern PATTERN = Pattern.compile("[^`!~@#$¥%^&*()+=\\[\\]\\\\|'\"“”‘’;;:《》,<>,?/?{}]*$");
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value != null) {
            Matcher matcher = PATTERN.matcher(value);
            return matcher.matches();
        }
        return true;
    }
}

小贴士:matcher.find()和mathche.matches()在一个Mather对象中只能调用一次,如果要二次调用,需要重新构建Mather对象,否则返回值将永远是false,这个坑有点深。

注解类定义

然后需要定义一个注解类,该注解类是上面定义规则类时所使用的,并且这个注解类就是请求参数类上直接使用的注解。

package com.xasj.common.annotation;

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

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

/**
 * @author 莫须有
 * @Date 2022/10/11 16:22
 * @Description 校验特殊字符注解
 */
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {SpecialCharacterMatch.class})
public @interface SpecialMatch {
    String message() default "不能包含除'-''_'外的特殊字符"; // 匹配失败提示消息内容
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

注解类包含几个其它的注解:
@Target:注解的使用目标,这里选择作用在字段(FIELD)和参数(PARAMTERE)上,它有8种类型,被定义在ElementType枚举类种
@Target的作用范围有类型如下:
1.@Target(ElementType.TYPE)——接口、类、枚举、注解
2.@Target(ElementType.FIELD)——字段、枚举的常量
3.@Target(ElementType.METHOD)——方法
4.@Target(ElementType.PARAMETER)——方法参数
5.@Target(ElementType.CONSTRUCTOR) ——构造函数
6.@Target(ElementType.LOCAL_VARIABLE)——局部变量
7.@Target(ElementType.ANNOTATION_TYPE)——注解
8.@Target(ElementType.PACKAGE)——包,用于记录java文件的package信息
@Retention:该注解作用是定义被它所注解的注解保留多久,这里选择RunTime,它的三中类型被定义在RetentionPolicy枚举类中
@Retention的类型包括:
1.@Retention(SOURCE):注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
2.@Retention(CLASS):注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
3.@Retention(RUNTIME):注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Documented:该注解与文档生成相关,具体作用如果一个注解@B,被@Documented标注,那么被@B修饰的类,生成文档时,会显示@B。如果@B没有被@Documented标准,最终生成的文档中就不会显示@B。(具体没有试过)
@Constraint:该注解用于标识运用的规则校验类,validatedBy 填写上面定义好的规则类

自定义注解使用

使用自定义注解和其它注解一样,@加注解类的类名
自定义参数校验注解_第1张图片

结果

校验的内容为字符串不包含出-和_外的所有特殊字符
自定义参数校验注解_第2张图片

总结

本次做的自定义注解完全可以使用@Pattern正则匹配注解来完成,但是使用@Pattern注解每次都需要些很长的正则表达式,因此使用自定义注解来实现这个匹配效果,定义自定义注解可以实现重用,根据具体的业务需要定义不同的注解可以有效的提升效率。

你可能感兴趣的:(有用的小知识,java,spring,1024程序员节)