springboot使用AOP实现验证

springboot使用AOP实现验证

先写注释类ValidateGroup

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ValidateGroup {
    public ValidateFiled[] fileds() ;
}

注释类ValidateFiled


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ValidateFiled {

    /**
     * 参数索引位置
     */
    int index() default -1 ;

    /**
     * 如果参数是基本数据类型或String ,就不用指定该参数,如果参数是对象,要验证对象里面某个属性,就用该参数指定属性名
     */
    String filedName() default "" ;

    /**
     * 正则验证
     */
    String regStr() default "";

    /**
     * 是否能为空  , 为true表示不能为空 , false表示能够为空
     */
    boolean notNull() default false;

    /**
     * 是否能为空  , 为true表示不能为空 , false表示能够为空
     */
    int maxLen() default -1 ;

    /**
     * 最小长度 , 用户验证字符串
     */
    int minLen() default -1 ;

    /**
     *最大值 ,用于验证数字类型数据
     */
    int maxVal() default -1 ;

    /**
     *最小值 ,用于验证数值类型数据
     */
    int minVal() default -1 ;

    int size() default -1 ;

    boolean images() default false;
}

验证类ValidateAspectHandel


import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import com.chqcontrol.annotation.ValidateFiled;
import com.chqcontrol.annotation.ValidateGroup;
import com.chqcontrol.exception.ValidException;
import com.common.other.APIErrorCode;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 * 验证注解处理类
 * @author zhoufeng
 */
@Component
@Aspect
public class ValidateAspectHandel {

    /**
     * 使用AOP对使用了ValidateGroup的方法进行代理校验
     * @throws Throwable
     */
    @SuppressWarnings({ "finally", "rawtypes" })
    @Around("@annotation(com.chqcontrol.annotation.ValidateGroup)")
    //@Before(("execution(* com.chqcontrol.service.*.*(..)) && @annotation(validateGroup)"))
    public Object validateAround(ProceedingJoinPoint joinPoint) throws Throwable  {
        boolean flag = false ;
        ValidateGroup an = null;
        Object[] args =  null ;
        Method method = null;
        Object target = null ;
        String methodName = null;

        methodName = joinPoint.getSignature().getName();
        target = joinPoint.getTarget();
        method = getMethodByClassAndName(target.getClass(), methodName);    //得到拦截的方法
        args = joinPoint.getArgs();     //方法的参数
        an = (ValidateGroup)getAnnotationByMethod(method ,ValidateGroup.class );
        flag = validateFiled(an.fileds() , args);

        if(flag){
            System.out.println("验证通过");
            return joinPoint.proceed();
        }else{  //这里使用了Spring MVC ,所有返回值应该为Strng或ModelAndView ,如果是用Struts2,直接返回一个String的resutl就行了
            System.out.println("验证未通过");
            Class returnType = method.getReturnType();  //得到方法返回值类型
            if(returnType == String.class){ //如果返回值为Stirng
                return "/error.jsp";        //返回错误页面
            }else if(returnType == ModelAndView.class){
                return new ModelAndView("/error.jsp");//返回错误页面
            }else{  //当使用Ajax的时候 可能会出现这种情况
                throw new ValidException(APIErrorCode.JSON_ERROR);
            }
        }
    }

    public boolean validateFiledOne(String filedName,Object[] args,ValidateFiled validateFiled) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{

        Object arg = null;
        if("".equals(filedName) ){
            arg = args[validateFiled.index()];
        }else{
            arg = getFieldByObjectAndFileName(args[validateFiled.index()] ,
                    filedName);
        }

        if(validateFiled.notNull()){        //判断参数是否为空
            if(StringUtils.isEmpty(arg))
                return false;
        }else{      //如果该参数能够为空,并且当参数为空时,就不用判断后面的了 ,直接返回true
            if(arg == null )
                return true;
        }

        if(validateFiled.maxLen() > 0){      //判断字符串最大长度
            if(((String)arg).length() > validateFiled.maxLen())
                return false;
        }

        if(validateFiled.minLen() > 0){      //判断字符串最小长度
            if(((String)arg).length() < validateFiled.minLen())
                return false;
        }

        if(validateFiled.maxVal() != -1){   //判断数值最大值
            if( (Integer)arg > validateFiled.maxVal())
                return false;
        }

        if(validateFiled.minVal() != -1){   //判断数值最小值
            if((Integer)arg < validateFiled.minVal())
                return false;
        }
        if(validateFiled.size() != -1){   //判断数值最小值
            if(((String)arg).length() != validateFiled.size())
                return false;
        }

        if(!"".equals(validateFiled.regStr())){ //判断正则
            if(arg instanceof String){
                if(!((String)arg).matches(validateFiled.regStr()))
                    return false;
            }else{
                return false;
            }
        }
        if(validateFiled.images()){ //判断正则
            if(arg == null || ((MultipartFile[])arg).length == 0){
                return false;
            }
        }
        return true;
    }
    /**
     * 验证参数是否合法
     */
    public boolean validateFiled(ValidateFiled[] valiedatefiles , Object[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
        for (ValidateFiled validateFiled : valiedatefiles) {
            String fileName = validateFiled.filedName();
            String[] fileNames = fileName.split(",");
            for(String f : fileNames) {
                boolean flag = validateFiledOne(f, args,validateFiled);
                if(!flag){
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 根据对象和属性名得到 属性
     */
    public Object getFieldByObjectAndFileName(Object targetObj , String fileName) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
        String tmp[] = fileName.split("\\.");
        Object arg = targetObj ;
        for (int i = 0; i < tmp.length; i++) {
            Method methdo = arg.getClass().
                    getMethod(getGetterNameByFiledName(tmp[i]));
            arg = methdo.invoke(arg);
        }
        return arg ;
    }

    /**
     * 根据属性名 得到该属性的getter方法名
     */
    public String getGetterNameByFiledName(String fieldName){
        return "get" + fieldName.substring(0 ,1).toUpperCase() + fieldName.substring(1) ;
    }

    /**
     * 根据目标方法和注解类型  得到该目标方法的指定注解
     */
    public Annotation getAnnotationByMethod(Method method , Class annoClass){
        Annotation all[] = method.getAnnotations();
        for (Annotation annotation : all) {
            if (annotation.annotationType() == annoClass) {
                return annotation;
            }
        }
        return null;
    }

    /**
     * 根据类和方法名得到方法
     */
    public Method getMethodByClassAndName(Class c , String methodName){
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            if(method.getName().equals(methodName)){
                return method ;
            }
        }
        return null;
    }
}

最后在service方法中加入注解使用

@ValidateGroup(fileds = {
            //index=0 表示下面方法的第一个参数,也就是person  nutNull=true 表示不能为空
            // @ValidateFiled(index = 0, notNull = true, filedName = "account,name,post"),
            // @ValidateFiled(index = 0, notNull = true, filedName = "phone", regStr = phone_pattern),
//            @ValidateFiled(index = 0, notNull = true, filedName = "ezPhone", size = 6)
    })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

97年的典藏版

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值