spring boot 自定义校验参数注解

springboot接口在接收参数时,除了对参数的类型限制外,有时也需要针对参数进行一系列的校验,Validator为我们提供一些固定格式的校验,例如:email、blank、length等格式,前两天在搬砖的时候就遇到这样的需求,一个参数为IP,所以需要验证是否满足IP格式。
当然,IP格式校验不可能只是验证是否有三个“.”,需要验证IP每一位上是否在0-255之间,Validator没有提供这样的校验,我们可以来自定义Validator的注解来满足我们的需求。

打开Validator引用的jar包可以看到咱们熟悉的一些注解。
在这里插入图片描述
虽然源码没看过,不过照葫芦画瓢还不会么,注解找到了,那么再找一下注解的处理类不就完事了。
在这里插入图片描述
在这里插入图片描述
找到了ConstraintValidator接口,看了一下他的实现类,眼熟不。。。。照着实现类写一下,再注入到容器中,那么在执行其他验证时,就会执行咱们自定义的注解。
以@Max注解为例,查看其实现类
在这里插入图片描述
其实现类为一个抽像类,再往下看,他的子类扩展了他的一些功能,那么我们就照着这个抽像类来写就行。

定义注解

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * @Author: Seven
 */
@Target({ ElementType.METHOD ,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = IPValidator.class)
public @interface IpCheck {

    String message() default "{com.seven.dto.IpCheck.message}";

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

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

}

注解处理类

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

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

/**
 * @Author: Seven
 */
@Component
public class IPValidator implements ConstraintValidator<IpCheck, CharSequence> {

    private static final String regex = "(((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))";

    @Override
    public void initialize(IpCheck constraintAnnotation) {
        System.out.println("进初始化方法了");
    }

    @Override
    public boolean isValid(CharSequence val, ConstraintValidatorContext constraintValidatorContext) {
        //验证逻辑
        if(StringUtils.isEmpty(ip)){
            return true;
        }
        Pattern pattern = Pattern.compile(regex);    // 编译正则表达式
        Matcher matcher = pattern.matcher(ip);    // 创建给定输入模式的匹配器
        return matcher.matches();
    }
} 

记得加上@Compont 注解。

将注解加在接收参数的属性上。
然后验证接口。

发送请求测试:
在这里插入图片描述
如果没有引用Validator校验,那么 也可以使用AOP的环绕通知来实现校验

/**
 * @Author: Seven
 */
@Aspect
@Component
public class IpPamterCheck {
    @Around(value = "@annotation(com.seven.IpCheck)")
    public Object test(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        if(args == null ){
            return point.proceed();
        }
        for (int i = 0; i < args.length; i++) {
            Field[] declaredFields = args[i].getClass().getDeclaredFields();
            for (int j = 0; j < declaredFields.length; j++) {
                boolean ip = declaredFields[j].getName().equals("ip");
                String name = "";
                if(ip){
                    name = declaredFields[j].getName().substring(0,1).toUpperCase() + declaredFields[j].getName().substring(1);
                    // 获取方法
                    Method m = args[i].getClass().getMethod("get" + name);
                    // 调用getter方法获取属性值
                    String value = (String) m.invoke(args[i]);
                    System.out.println(value);
                    Boolean ipCheck = CheckUtil.IPCheck(value);
                    if(!ipCheck){
                        return ApiResult.error(40001,"IP format is error !");
                    }
                }
            }
        }
        return point.proceed();
    }
}

如果你还有什么好的方法,可以评论告诉我下。。。并且上面有什么错误的地方,可以给我提出。。我尽快更改。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值