使用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
- 使用ProceedingJoinPoint获取当前请求的方法等参数——spring mvc拦截器
- ProceedingJoinPoint获取当前方法
- Spring中的AOP(五)——在Advice方法中获取目标方法的参数ProceedingJoinPoint
- Spring MVC请求参数获取的方法
- Cxf拦截器中获取当前请求的参数
- spring mvc 拦截器打印详细的请求参数信息
- 【Spring】—— Spring3 MVC请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- SPRING MVC 的请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- SPRING MVC 的请求参数获取的几种方法
- SPRING MVC 的请求参数获取的几种方法
- SPRING MVC 的请求参数获取的几种方法
- Spring MVC 的请求参数获取的几种方法
- C语言宏中"#"和"##"的用法
- TP3.2.3使用page分页类对查询结果进行分页时的问题
- NFC功能移植pn54x系列
- 程序员面试金典: 9.9 递归和动态规划 9.11求布尔表达式的表达个数
- iOS--bool和BOOL的区别
- 使用ProceedingJoinPoint获取当前请求的方法等参数——spring mvc拦截器
- Dozer轻松实现对象间属性复制
- android 5.0后对于apk 跑32 64 的逻辑
- U8Server——分布式环境下唯一订单号生成规则
- C语言程序设计---10:利用文件保存数据
- do{...}while(0)的意义和用法
- CLRegion监听区域
- 屏幕底部控件始终在软键盘顶端
- POJ 3468 A Simple Problem with Integers【线段树区间更新入门题】