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.在切面类中获取请求参数名和参数值


/** 
  
  * @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;     
  
     }     
  
 }