自定义参数校验注解的使用

前言

在我们工作业务当中,参数校验是一项必不可少的步骤,虽然 javax.validation包下面自带了很多校验注解,但是很多情况下我们根据业务会出现自己特有的校验方式,这时候就需要我们使用注解来实现自定义校验的方式。


一、遇到的问题

我现在想要校验某个入参的一个字段的取值范围是否正确,他的取值范围可能记录在数据库,也可能记录在redis,也可能是列举尽的固定几个,总之需要根据不同情况判断.

二、操作

1.自定义一个注解,设置好作用域和内置属性等等

代码如下(示例):

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {DictValidator.class})  // 校验规则写在DictValidator类
public @interface DictValid {

    String message() default "";

    // 分组校验
    Class<?>[] groups() default {};

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

    /**
     * mysql ->写一个能从mysql分辨找出的标识即可
     * redis -> key
     * 固定列举 -> 逗号隔开,如(1,2,3)
     * 
     * @return
     */
    String target() default "";

    /**
     * 根据type判断是从什么地方取值校验合法性,1:mysql,2:redis,3:固定列举
     *
     * @return
     */
    String type() default "1";

}

2.编写校验规则DictValidator类

代码如下(示例):

public class DictValidator implements ConstraintValidator<DictValid, Object> {

    private DictValid annotation;
 
    @Override
    public void initialize(DictValid constraintAnnotation) {
        annotation = constraintAnnotation;
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        boolean result = false;
        String target = annotation.target();
        String type = annotation.type();
        if (o != null && !"".equals(o.toString().trim())) {
            String value = o.toString();
            if ("1".equals(type)) {
                result = checkTypeByDB(target, value);
            }
            if ("2".equals(type)) {
                result = checkTypeByRedis(target, value);
            }
            if ("3".equals(type)) {
                result = checkTypeByEnumerate(target, value);
            }

        }
        return result;
    }

    private boolean checkTypeByDB(String target, String value) {
        // 从数据库取值作比
    }

    private boolean checkTypeByRedis(String target, String value) {
        // target为key,直接从redis取值作比
    }
    
    private boolean checkTypeByEnumerate(String target, String value) {
        List<String> dictList = Arrays.asList(target.split(","));
        return dictList.contains(value);
    }
}

3.使用

代码如下(示例):

// 实体类字段的写法
@DictValid(target = RedisConstants.BOOK_TYPE, message = "bookType is error", type = "2")
private String bookType;

// 在入参加上@Valid即可
public Response<Object> save(@Valid @RequestBody BookVo bookVo ){

}

总结

本文讲述了自定义参数校验的简单使用,重点在于注解的实现类(本文为ConstraintValidator类)的写法,他得实现泛型接口ConstraintValidator<A extends Annotation, T>,第一个参数为我们的自定义的注解,第二个参数即为入参的类型。此接口的核心方法为boolean isValid(T var1, ConstraintValidatorContext var2),我们实现此接口主要就是在此方法写写我们的校验规则。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值