通过AOP+注解来实现参数的校验

在实际的java开发中,参数校验是个比较零碎繁琐的事情,但是却必不可少,本文通过aop来实现对参数的校验,可以节省大量的时间和提交代码的可读性与整洁性,方便更加集中的编写业务逻辑。

代码:

ParamCheckAop:

package com.yzs.plat.process.common.aop;

import com.yzs.plat.process.common.annotation.ValidateFiled;
import com.yzs.plat.process.common.annotation.ValidateGroup;
import com.yzs.plat.process.common.utils.oConvertUtils;
import com.yzs.plat.process.common.vo.Result;
import com.yzs.plat.process.modules.process.entity.SUserinfo;
import com.yzs.plat.process.modules.process.service.ISUserinfoService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.task.Task;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * 参数检查AOP
 */
@Aspect
@Component
@Slf4j
public class ParamCheckAop {
    @Autowired
    private ISUserinfoService userinfoService;
    @Autowired
    private ProcessEngine processEngine;
    @Around("@annotation(com.yzs.plat.process.common.annotation.ValidateGroup)")
    public Object validateAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Result<?> result = null ;
        ValidateGroup an;
        Object[] args ;
        Method method;
        Object target;
        String methodName;
        boolean flag = false; // 是否发生异常
        try{
            methodName = joinPoint.getSignature().getName();
            target = joinPoint.getTarget();
            method = getMethodByClassAndName(target.getClass(), methodName);    //得到拦截的方法
            args = joinPoint.getArgs();     //方法的参数
            an = (ValidateGroup)getAnnotationByMethod(method ,ValidateGroup.class );
            result = validateFiled(an.fileds() , args);
        }catch(Exception e){
            flag = true;
        }finally{
            if(result == null && !flag){
                log.info("参数校验---------验证通过-------------");
                return joinPoint.proceed();
            }
            else{
                log.info("参数校验---------验证未通过-----------");
                return result;
            }
        }
    }

    /**
     * 验证参数是否合法
     */
    public Result<?> validateFiled(ValidateFiled[] valiedatefiles , Object[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
        for (ValidateFiled validateFiled : valiedatefiles) {
            Object arg;
            if("".equals(validateFiled.filedName()) ){
                arg = args[validateFiled.index()];
            }else{
                arg = getFieldByObjectAndFileName(args[validateFiled.index()] ,
                        validateFiled.filedName() );
            }
            if(validateFiled.notNull()){        //判断参数是否为空
                if(arg == null )
                    return Result.error(validateFiled.msg());
            }else{      //如果该参数能够为空,并且当参数为空时,就不用判断后面的了 ,直接返回true
                if(arg == null )
                    return null;
            }
            if(validateFiled.maxLen() > 0){      //判断字符串最大长度
                if(((String)arg).length() > validateFiled.maxLen())
                    return Result.error(validateFiled.msg());
            }

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

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

            if(validateFiled.minVal() != -1){   //判断数值最小值
                if((Integer)arg < validateFiled.minVal())
                    return Result.error(validateFiled.msg());
            }

            if(!"".equals(validateFiled.regStr())){ //判断正则
                if(arg instanceof String){
                    if(!((String)arg).matches(validateFiled.regStr()))
                        return Result.error(validateFiled.msg());
                }else{
                    return Result.error(validateFiled.msg());
                }
            }
            if(validateFiled.isUid()) { // 验证uid是否存在
                if(oConvertUtils.isEmpty(arg)){
                    return Result.error("uid不能为空!");
                }
                SUserinfo suid = userinfoService.query().eq("SUIID", arg).one();
                if(suid == null) {
                    return Result.error(validateFiled.msg());
                }
            }
            if(validateFiled.isTaskId()) { // 验证taskId是否存在
                HistoricTaskInstance historicTaskInstance = processEngine.getHistoryService().createHistoricTaskInstanceQuery().taskId(arg.toString()).singleResult();
                Task task = processEngine.getTaskService().createTaskQuery().taskId(arg.toString()).singleResult();
                if(historicTaskInstance == null && task == null) {
                    return Result.error(validateFiled.msg());
                }
            }
        }
        return null;
    }

    /**
     * 根据对象和属性名得到 属性
     */
    public Object getFieldByObjectAndFileName(Object targetObj , String fileName) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, 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;
    }
}

ValidateGroup:

package com.yzs.plat.process.common.annotation;

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 {  
    ValidateFiled[] fileds() ;
}  

ValidateFiled:

package com.yzs.plat.process.common.annotation;

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 {

    /**
     * 提示信息
     */
    String msg() default "";
    /** 
     * 参数索引位置 
     */  
    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 ;

    /**
     * 是否是uid
     * @return
     */
    boolean isUid() default false;

    /**
     * 是否是taskId
     * @return
     */
    boolean isTaskId() default false;
}

具体使用:

  /**
     * 个人-启动一个流程
     */
    @PostMapping("/startupProcess")
    @ApiOperation("个人-启动一个流程")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "delta", value = "增量", dataType = "BigDecimal"),
            @ApiImplicitParam(name = "name", value = "姓名", dataType = "String"),
            @ApiImplicitParam(name = "note", value = "注解", dataType = "String"),
            @ApiImplicitParam(name = "processDefinitionId", value = "流程定义Id", dataType = "String"),
            @ApiImplicitParam(name = "tenantId", value = "租户Id", dataType = "String"),
            @ApiImplicitParam(name = "uid", value = "用户id", dataType = "String"),
            @ApiImplicitParam(name = "attachment", value = "附件", dataType = "JSONObject")
    })
    @ValidateGroup(fileds = {
            @ValidateFiled(index=0, notNull=true,msg = "delta不能为空!"),
            @ValidateFiled(index=1, notNull=true,msg = "name不能为空!"),
            @ValidateFiled(index=2, notNull=true,msg = "note不能为空!"),
            @ValidateFiled(index=3, notNull=true,msg = "processDefinitionId不能为空!"),
            @ValidateFiled(index=4, notNull=true,msg = "tenantId不能为空!"),
            @ValidateFiled(index=5, notNull=true,msg = "uid不能为空!"),
            @ValidateFiled(index=5, isUid=true,msg = "uid(用户id)不存在!"),
    })
    public Result<?> startProcess(
            BigDecimal delta,
            String name,
            String note,
            String processDefinitionId,
            String tenantId,
            String uid,
            String attachment){

运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值