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

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

解决方案是可以使用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;
	@Autowired
	RybAuditLogService 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 map = (Map)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-1){
						flag = false;
						break;
					}
				}
			}
			return flag;
		}
	    
	    
	    
	    /**
		 * 类型判断
		 * @param map
		 * @return
		 */
	    public boolean typeJudge(Map 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)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 map = (Map)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;
	    }
}


你可能感兴趣的:(使用ProceedingJoinPoint获取当前请求的方法等参数——spring mvc拦截器)