自定义Spring的Aop切面类拦截业务请求,并获取到请求的参数名和参数值

来源:互联网 发布:ubuntu sublime tar 编辑:程序博客网 时间:2024/06/05 19:20

1.问题引入

本次需求是涉及到审核操作,添加,修改,删除人员,商品时如果需要审核,则先向审核队列表中插入审核信息,不需要审核时直接操作业务表(用户表)。这里许多操作都需要判断是否需要审核,所以我就定义了一个sping的切面类来拦截所有进入业务层的方法(也可以使用springmvc的拦截器)。第二个问题是在切面类中如何获取请求的参数,和参数对应的值。至此有两个问题需要解决:⑴如何定义一个切面类;⑵在这个切面类中如何获取请求参数。

2.定义切面类

下面是切面类的核心代码,需要注意的是,在这里需要引入jar包aspectj,我引入的是1.7.4的,同时还要在spring.xml的配置文件中进行如下配置。
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
 <context:component-scan base-package="com.ynet.finmall.innermanage.service.impl" />
 <context:component-scan base-package="com.ynet.finmall.innermanage.config" />
service.impl是要扫描的业务层实现类所在的包。config是切面类ReviewValidate所在的包。到这里切面类已经定义完毕,可以根据自己的需要配置切入点。代码如下:

@Component
@Aspect
public class ReviewValidate {
@Around(value = "execution(* com.ynet.finmall.innermanage.service.impl.*.*(..))")
public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();

//获取到请求参数,判断是否需要审核,代码略
if(需要审核){
//执行通用的审核操作,代码略。。。
       return null;
}else{
//不需要审核,直接执行普通的增删改操作
return joinPoint.proceed();
}
}

3.在切面类中获取请求参数名和参数值

如果请求参数在在springmvc中是以一个实体类的形式接收的或者jdk是1.8都是可以通过Object[] args = joinPoint.getArgs();这句代码获取到请求参数和参数值的,但是如果以Map形式接的参数,则要费点力气了。下面是所有实现代码(需要引入javassist的jar包)。
/**
 * @author 刘俊重
 * @Description 审核校验
 * 所有的service业务方法都会先走这个方法,
 * 先判断本操作需不需要审核,如果需要审核则插入审核队列表,
 * 不需要审核则直接插入相关业务表
 * @date 2017年7月5日
 */
@Component
@Aspect
public class ReviewValidate {


@Autowired
private ImAuthQueueDao imAuthQueueDao;

private static Logger logger = LoggerFactory.getLogger(ReviewValidate.class);

@Around(value = "execution(* com.ynet.finmall.innermanage.service.impl.*.*(..))")
public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();

        String classType = joinPoint.getTarget().getClass().getName();    
        Class<?> clazz = Class.forName(classType);    
        String clazzName = clazz.getName();    
        String methodName = joinPoint.getSignature().getName(); //获取方法名称   
         //获取参数名称和值  
        Map<String,Object > nameAndArgs = this.getFieldsName(this.getClass(), clazzName, methodName,args);   
        //nameAndArgs的两种类型,用实体类接收的类似这样: reqParams=com.ynet.finmall.innermanage.event.SaveOrUpdateRoleReqParam@616b9c0e
        //用Map<String,Object>接收的是这样:menuNo=56473283,遍历这个map区分两种不同,使用不同的取值方式。
        //根据获取到的值所属的不同类型通过两种不同的方法获取参数
        boolean flag = false;
        if(nameAndArgs!=null && nameAndArgs.size()>0){
            for (Map.Entry<String, Object> entry : nameAndArgs.entrySet()) {  
            logger.info(">>>>>>>>>>>>>>类型"+entry.getValue().getClass().toString());
            if(entry.getValue() instanceof String){
            flag = true;
            break;  //跳出循环
            }
            }  
        }
        StringBuffer sb = new StringBuffer();
        if(flag){
        //从Map中获取
        sb.append(JSONObject.toJSONString(nameAndArgs))
         .append(",");
        }else{
    if (args != null) {
    for (Object object : args) {
    if (object != null) {
    if (object instanceof MultipartFile||object instanceof ServletRequest||object instanceof ServletResponse) {
    continue;
    }
    sb.append(JSONObject.toJSONString(object))
     .append(",");
    }
    }
    }
        }
String isReview = "";
String arg = sb.toString().substring(0, sb.toString().length()-1);
JSONObject cache_json = new JSONObject();
if(arg!=null){
cache_json = JSONObject.parseObject(arg);
//是否需要审核
isReview = cache_json.getString("isReview");
}
logger.info(">>>>>>>>>>>>>>>>>>>"+cache_json);
if(isReview!=null && isReview!="" && DbEnum.CommonReqParam.IsReview.NEEDREVIEW.equals(isReview)){
//需要审核,执行存入审核队列操作
//如果本操作是需要审核的,则将本操作缓存在操作队列中,审核通过时才真正将新增操作员操作插入数据库
       ImAuthQueue imAuth = new ImAuthQueue();
       imAuth.setIaqBatchNo(UUID.randomUUID().toString().replace("-", ""));
       imAuth.setIaqPk(cache_json.toJSONString());
       imAuth.setIaqBsnCode(cache_json.getString("businessCode"));
       imAuth.setIaqOpType(cache_json.getString("operatorType"));
       imAuth.setIaqSubmitUserId(cache_json.getString("submitUserId"));
       imAuth.setIaqDescribe(cache_json.getString("describe"));

      //插入审核队列表中
       imAuthQueueDao.insert(imAuth);
       return null;
}else{
//不需要审核,直接执行普通的增删改操作
return joinPoint.proceed();
}
}

/**
* @Description 获取字段名和字段值
* @Author 刘俊重
* @date 2017年7月6日 
* @return Map<String,Object>
*/
private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws Exception {   
        Map<String,Object > map=new HashMap<String,Object>(); 


        ClassPool pool = ClassPool.getDefault();    
        ClassClassPath classPath = new ClassClassPath(cls);    
        pool.insertClassPath(classPath);    
            
        CtClass cc = pool.get(clazzName);    
        CtMethod cm = cc.getDeclaredMethod(methodName);    
        MethodInfo methodInfo = cm.getMethodInfo();  
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();    
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);    
        if (attr == null) {    
            // exception    
        }    
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;    
        for (int i = 0; i < cm.getParameterTypes().length; i++){    
            map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名    
        }    
        return map;    
    }    
}


本文参考文档:http://blog.csdn.net/thinkingt_t/article/details/68951703
阅读全文
3 0
原创粉丝点击