使用ProceedingJoinPoint获取当前请求的方法等参数——spring mvc拦截器

来源:互联网 发布:纵横九州神羽进阶数据 编辑:程序博客网 时间:2024/06/05 22:44

在项目中常常需要顾虑请求参数中的特殊字符,比如+,<,>等

解决方案是可以使用spring mvc 的拦截器,配合aspectJ使用

package com.cpic.core.web;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.math.BigDecimal;import java.util.Date;import java.util.Enumeration;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.reflect.MethodSignature;import org.jfree.util.Log;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import com.cpic.caf.compon.business.common.entity.CodeEntryEO;import com.cpic.caf.compon.tech.utils.JsonUtils;import com.cpic.caf.compon.tech.utils.StringUtils;import com.cpic.caf.pub.app.context.SpringAppContextUtil;import com.cpic.caf.pub.security.context.SecurityContext;import com.cpic.core.cache.DataCacheManager;import com.cpic.core.filter.FilterUtils;import com.cpic.core.httpHandler.entity.Response;import com.cpic.cxyb.entity.LogManager;import com.cpic.cxyb.entity.RybAuditLog;import com.cpic.cxyb.service.LogManagerService;import com.cpic.cxyb.service.RybAuditLogService;import com.cpic.cxyb.threads.RybAuditLogSyncToDBThread;import com.cpic.framework.entity.ResponseContent;import com.cpic.xybx.security.MyUserInfoImpl;import com.cpic.xybx.tools.CpicmIPUtil;public class FilterTextSpecialString {public static final Logger logger = LoggerFactory.getLogger ( FilterTextSpecialString.class );DataCacheManager dataCacheManager;LogManagerService logManagerService;@AutowiredRybAuditLogService rybAuditLogService;public static final String[] APP_METHOD = {"innerServerController.submit,innerServerController.submitContent"};public static final String RETURN_TYPE_AJAX = "ResponseContent";public static final String RETURN_TYPE_MV = "ModelAndView";public static final String RETURN_TYPE_MAP = "Map";public static final String RETURN_TYPE_VOID = "void";public static final String RETURN_TYPE_STRING = "String";//特殊字符的判断    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {    this.dataCacheManager = (DataCacheManager)SpringAppContextUtil.getBean("dataCacheManager");        this.logManagerService = (LogManagerService)SpringAppContextUtil.getBean("logManagerService");    //从数据库获取文本框特殊字符过滤信息   CodeEntryEO codeEntry = null;   String speCharactor = "";   String method = pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName();   //获取映射方法   try{   String returnType = pjp.getSignature().toString().split(" ")[0];        if(StringUtils.isNotBlank(returnType) && RETURN_TYPE_MV.equals(returnType)){   Method targetMethod = ((MethodSignature)(pjp.getSignature())).getMethod();       Class<?> classtest = targetMethod.getDeclaringClass();          String classAnnotationValue = "";     String methodAnnotationValue = "";     Annotation[]  classAnnotation = classtest.getAnnotations();     for (int i = 0; i < classAnnotation.length; i++) {     if(classAnnotation[i] instanceof RequestMapping){     RequestMapping requestmap = (RequestMapping) classAnnotation[i];     if(requestmap.value()[0] != null){     classAnnotationValue = (requestmap.value())[0];     }     break;     }  }          if(StringUtils.isNotBlank(classAnnotationValue)){     Annotation[] methodAnnotation = targetMethod.getAnnotations();       for (int i = 0; i < methodAnnotation.length; i++) {       if(methodAnnotation[i] instanceof RequestMapping){       RequestMapping requestmap = (RequestMapping) methodAnnotation[i];         if(requestmap.value()[0] != null){         methodAnnotationValue = (requestmap.value())[0];         }         break;       }           }              String catalog = classAnnotationValue+"/"+methodAnnotationValue;        //增加审计日志          if(RybAuditLogSyncToDBThread.menuMap.get(catalog) != null){          MyUserInfoImpl user = (MyUserInfoImpl) SecurityContext.getCurrentUser();          //UserDefault user = (UserDefault)servletRequest.getAttribute("user");      RybAuditLog  auditLog = new RybAuditLog();      auditLog.setDatetime(new Date());      auditLog.setInterfacecode(catalog);      auditLog.setKind("web");      String requestName = (String) RybAuditLogSyncToDBThread.menuMap.get(catalog);      if(StringUtils.isNotBlank(requestName))auditLog.setInterfacename(requestName);      if(user != null){      String usertype = user.getUserType();      auditLog.setUnitcode(user.getOrgCode());      auditLog.setUsercode(user.getUserCode());      auditLog.setUsername(user.getUsername());      auditLog.setUsertype(usertype);      auditLog.setOrgid(user.getOrgId());      if(StringUtils.isNotBlank(usertype) && "CPICUser".equals(user.getUserType())){      auditLog.setUnitname((String)(RybAuditLogSyncToDBThread.orgMap).get(user.getOrgCode()));      }else{      auditLog.setUnitname((String)(RybAuditLogSyncToDBThread.outsideOrgMap).get(user.getOrgCode()));      }            }      this.rybAuditLogService.log(auditLog);          }     }        }   }catch(Exception e){   Log.error("记录审计日志出错"+e.getMessage());   }            boolean appFlag = false;   //判断是否是app   for(int i = 0 ; i < APP_METHOD.length ; i++){   if(method.indexOf(APP_METHOD[i]) >= 0){   appFlag = true;   break;   }   }      //文本过滤器不过滤类和方法,配置在数据库中为:类名.方法名,类名.方法名      CodeEntryEO codeEntryEO = dataCacheManager.getCodeEntryCacheByName("FilterConfig","TextSpecialCharactersException");               String exception = "";      if(codeEntryEO != null){      exception = codeEntryEO.getName();   }      String[] exceptions = exception.split(",");      boolean exec = true;      for(int i = 0 ; i < exceptions.length ; i ++){      if(method.indexOf(exceptions[i]) >= 0){      exec = false;   break;   }      }      boolean flag = false;//默认为假,有可能该Ctrl为例外或者没有参数则不作校验      if(exec){    if(appFlag ){    codeEntry = dataCacheManager.getCodeEntryCacheByName("FilterConfig","appTextSpecialCharacters");        }else{        codeEntry = dataCacheManager.getCodeEntryCacheByName("FilterConfig","TextSpecialCharacters");        }        if (codeEntry != null){        speCharactor = codeEntry.getName();        }        String[] list = {};        //如果过滤规则为空,则不过滤        if(StringUtils.isNotEmpty(speCharactor)){        //特殊字符串数组            list = speCharactor.split(",");        }        if(list.length > 0 && pjp.getArgs() != null && pjp.getArgs().length > 0){        for (int i = 0; i < pjp.getArgs().length; i++) {        if(pjp.getArgs()[i] instanceof LinkedHashMap){        Map<String,Object> map = (Map<String,Object>)pjp.getArgs()[i];        flag = typeJudge(map,list,method);        }else if(pjp.getArgs()[i] instanceof HttpServletRequest){        HttpServletRequest req = ((HttpServletRequest)pjp.getArgs()[i]);        Enumeration enu = req.getParameterNames();      while(enu.hasMoreElements()){      String paraName=(String)enu.nextElement();      if(req.getParameter(paraName) != null){    flag = FilterUtils.checkTextStringValue(req.getParameter(paraName).toUpperCase(),list);    }    //包含特殊字符退出循环    if(flag){    logger.info(method + "参数名为:"+paraName+" 的值为:"+req.getParameter(paraName)+" 中包含特殊字符。");    break;    }    }         }else if(pjp.getArgs()[i] instanceof String){        flag = FilterUtils.checkTextStringValue(pjp.getArgs()[i].toString().toUpperCase(),list);        }        //包含特殊字符退出循环,不校验下一个参数    if(flag){    break;    }        }        }      }        //没有特殊字符校验通过,调用ctrl方法执行业务        Object retVal = null;        if(!flag){        try{        retVal = pjp.proceed();         }catch(Exception e){        StackTraceElement stackTraceElement= e.getStackTrace()[e.getStackTrace().length-1];        stackTraceElement.getLineNumber();        logger.error ( "\n=========执行{}方法的{}行异常信息为:=========={}",method,stackTraceElement.getLineNumber(),e.fillInStackTrace ( ).toString ( ) );        //记录错误日志到数据库        LogManager logManager = new LogManager();        logManager.setErrormsg("执行" + method + "方法的" + stackTraceElement.getLineNumber() + "行发生错误:" + e.fillInStackTrace ( ).toString ( ));        logManager.setIp(CpicmIPUtil.getServerIp());        logManager.setCreattime(new Date());        String requestStr = getRequestStr(pjp);        logManager.setRequestmsg(requestStr);        logManager.setResponsemsg("系统异常:请联系系统管理员");        this.logManagerService.log(logManager);        //针对异常的处理        if(appFlag ){        Response response = new Response();response.setStatus(Response.STATUS_ERROR);response.setErrorCode(Response.ERROR_CODE_SYSTEM);response.setErrorMessage("系统异常:请联系系统管理员");retVal = response;        }else{        String returnType = pjp.getSignature().toString().split(" ")[0];        if(RETURN_TYPE_AJAX.equals(returnType)){        ResponseContent responseContent = new ResponseContent();responseContent.setResultState(false);responseContent.setErrorCode("-88888");responseContent.setMsg("系统异常:请联系系统管理员");retVal = responseContent;        }else if(RETURN_TYPE_MV.equals(returnType)){        //返回管理后台错误页面        ModelAndView mv = new ModelAndView("systemError");        mv.addObject("msg", "系统异常:请联系系统管理员");        retVal = mv;        }else if(RETURN_TYPE_STRING.equals(returnType)){        //返回管理后台错误页面        retVal = "systemError";        }else if(returnType.indexOf(RETURN_TYPE_MAP) >= 0){        Map responseContent = new HashMap();responseContent.put("resultState",false);responseContent.put("errorCode","-88888");responseContent.put("msg","系统异常:请联系系统管理员");retVal = responseContent;        }else if(returnType.indexOf(RETURN_TYPE_VOID) >= 0){        //void目前不作处理,如果扫描出问题,则在进行处理,把HttpServletResponse获得到,直接向页面输出以下字符串//        Map responseContent = new HashMap();//responseContent.put("resultState",false);//responseContent.put("errorCode","-88888");//responseContent.put("msg","系统异常:请联系系统管理员");//retVal = responseContent;        }        }        }        }else{//包含特殊字符        LogManager logManager = new LogManager();        logManager.setErrormsg("请求异常:请求参数不合法或请求参数被篡改");        logManager.setIp(CpicmIPUtil.getServerIp());        logManager.setCreattime(new Date());        String requestStr = getRequestStr(pjp);        logManager.setRequestmsg(requestStr);        logManager.setResponsemsg("请求异常:请求参数不合法或请求参数被篡改");        this.logManagerService.log(logManager);        if(appFlag ){        Response response = new Response();response.setStatus(Response.STATUS_ERROR);response.setErrorCode(Response.ERROR_CODE_SPECIAL_TEXT);response.setErrorMessage("请求异常:请求参数不合法或请求参数被篡改");retVal = response;        }else{        String returnType = pjp.getSignature().toString().split(" ")[0];        if(returnType.indexOf(RETURN_TYPE_AJAX) >= 0){        ResponseContent responseContent = new ResponseContent();responseContent.setResultState(false);responseContent.setErrorCode("-88888");responseContent.setMsg("请求异常:请求参数不合法或请求参数被篡改");retVal = responseContent;        }else if(returnType.indexOf(RETURN_TYPE_MV) >= 0){        //返回管理后台错误页面        ModelAndView mv = new ModelAndView("permissionError");        mv.addObject("msg", "请求异常:请求参数不合法或请求参数被篡改");        retVal = mv;        }else if(RETURN_TYPE_STRING.equals(returnType)){        //返回管理后台错误页面        retVal = "permissionError";        }else if(returnType.indexOf(RETURN_TYPE_MAP) >= 0){        Map responseContent = new HashMap();responseContent.put("resultState",false);responseContent.put("errorCode","-88888");responseContent.put("msg","请求异常:请求参数不合法或请求参数被篡改");retVal = responseContent;        }else if(returnType.indexOf(RETURN_TYPE_VOID) >= 0){        //void目前不作处理,如果扫描出问题,则在进行处理,把HttpServletResponse获得到,直接向页面输出以下字符串//        Map responseContent = new HashMap();//responseContent.put("resultState",false);//responseContent.put("errorCode","-88888");//responseContent.put("msg","请求异常:请求参数不合法或请求参数被篡改");//retVal = responseContent;        }        }        }                 return retVal;      }              public static boolean checkTextStringValue(String str,String[] list){boolean flag = true;if(str!=null&&!"".equals(str)){for(int i=0;i<list.length;i++){if(str.indexOf(list[i])>-1){flag = false;break;}}}return flag;}                /** * 类型判断 * @param map * @return */    public boolean typeJudge(Map<String, Object> map,String[] list,String method) {    boolean flag = false;    for (String key : map.keySet()) {    try{    if(map.get(key) instanceof Integer){    continue;        }else if(map.get(key) instanceof Long){        continue;        }else if(map.get(key) instanceof String){        flag = FilterUtils.checkTextStringValue(map.get(key).toString().toUpperCase(),list);        if(flag){        logger.info(method + "|参数名为:"+key+" 的值为:"+map.get(key).toString()+" 中包含特殊字符。");        break;        }            }else if(map.get(key) instanceof Date){            continue;            }else if(map.get(key) instanceof BigDecimal){            continue;            }else if(map.get(key) instanceof List){//类型为list            continue;                }else if(map.get(key) instanceof Map){//类型为map            try{            if(map.get(key) != null && !"".equals ( map.get(key) )){            flag = typeJudge((Map<String,Object>)map.get(key),list,method);            if(flag){            logger.info(method + "|参数名为:"+key+" 的值为:"+map.get(key).toString()+" 中包含特殊字符。");            break;            }            }            }catch (Exception e) {            logger.error ( "\n=========异常信息为:==========\n{}",e.fillInStackTrace ( ).toString ( ) );}            }    }catch(Exception e){    logger.error ( "\n=========异常信息为:==========\n{}",e.fillInStackTrace ( ).toString ( ) );    }    }    return flag;    }        private String getRequestStr(ProceedingJoinPoint pjp){    String requestStr = "";    if(pjp.getArgs() != null && pjp.getArgs().length > 0){        for (int i = 0; i < pjp.getArgs().length; i++) {        if(pjp.getArgs()[i] instanceof LinkedHashMap){        Map<String,Object> map = (Map<String,Object>)pjp.getArgs()[i];        requestStr += "Map参数值为:" + JsonUtils.objToJson(map) + "|";        }else if(pjp.getArgs()[i] instanceof HttpServletRequest){        HttpServletRequest req = ((HttpServletRequest)pjp.getArgs()[i]);        Enumeration enu = req.getParameterNames();          requestStr += "HttpServletRequest参数值为:" + JsonUtils.objToJson(enu) + "|";        }else if(pjp.getArgs()[i] instanceof String){        requestStr += "HttpServletRequest参数值为:" + pjp.getArgs()[i].toString() + "|";        }        }        }    return requestStr;    }}


0 0