spring boot 自定义校验参数注解

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

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

定义注解

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 注解。

将注解加在接收参数的属性上。
spring boot 自定义校验参数注解_第5张图片

发送请求测试:
spring boot 自定义校验参数注解_第6张图片
如果没有引用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();
    }
}

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

你可能感兴趣的:(笔记,java,aop,spring)