package com.qjc.aop; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @Description: 切面 * @Author: qjc * @Date: 2020/4/20 */ @Aspect @Slf4j @Component public class TestAspect { @Pointcut("execution(* com.qjc.controller.TestController.*(..))") // @Pointcut("execution(* com.qjc.controller..*.*(..))") //切所有controller public void pointcut() { } @Before("pointcut()") public void beforeControllerMethod(JoinPoint joinPoint) { log.info("前置通知!!!!方法执行前执行"); } @Around("pointcut()") public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { String uuIdTrace = UUID.randomUUID().toString().replace("-", ""); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); //IP地址 String ipAddr = getRemoteHost(request); // String url = request.getRequestURL().toString(); String requestMethod = request.getMethod(); String requestURI = request.getRequestURI(); String reqParam = preHandle(proceedingJoinPoint, request);//获取请求参数 log.info(uuIdTrace + " 环绕通知,执行方法前,请求源IP:【{}】,请求方法:【{}】,请求URL:【{}】,请求参数:【{}】", ipAddr, requestMethod, requestURI, reqParam); long start = System.currentTimeMillis(); Object result = proceedingJoinPoint.proceed();//执行方法,获取响应信息 String respParam = postHandle(result); log.info(uuIdTrace + " 环绕通知,执行方法后,请求源IP:【{}】,请求URL:【{}】,返回参数:【{}】,执行耗时 : {}", ipAddr, requestURI, respParam, (System.currentTimeMillis() - start) + "ms"); return result; } @After("pointcut()") public void afterControllerMethod(JoinPoint joinPoint) { log.info("后置通知:方法执行完后执行"); } @AfterReturning(returning = "result", pointcut = "pointcut()") public void doAfterReturnint(Object result) { log.info("后置通知,方法执行完后执行,响应信息为:{}", JSONObject.toJSONString(result)); } /** * 入参数据 * * @param joinPoint * @param request * @return */ private String preHandle(ProceedingJoinPoint joinPoint, HttpServletRequest request) { try { Map<String, Object> fieldsName = getFieldsName(joinPoint); return JSON.toJSONString(fieldsName); } catch (Exception e) { log.warn("切面获取请求参数出现异常", e); return null; } } private Map<String, Object> getFieldsName(JoinPoint joinPoint) throws Exception { String classType = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); // 参数值 Object[] args = joinPoint.getArgs(); Class<?>[] classes = new Class[args.length]; for (int k = 0; k < args.length; k++) { // 对于接受参数中含有MultipartFile,ServletRequest,ServletResponse类型的特殊处理,我这里是直接返回了null。(如果不对这三种类型判断,会报异常) if (args[k] instanceof MultipartFile || args[k] instanceof ServletRequest || args[k] instanceof ServletResponse) { return null; } if (!args[k].getClass().isPrimitive()) { // 当方法参数是基础类型,但是获取到的是封装类型的就需要转化成基础类型 // String result = args[k].getClass().getName(); // Class s = map.get(result); // 当方法参数是封装类型 Class s = args[k].getClass(); classes[k] = s == null ? args[k].getClass() : s; } } ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); // 获取指定的方法,第二个参数可以不传,但是为了防止有重载的现象,还是需要传入参数的类型 Method method = Class.forName(classType).getMethod(methodName, classes); // 参数名 String[] parameterNames = pnd.getParameterNames(method); // 通过map封装参数和参数值 HashMap<String, Object> paramMap = new HashMap(); for (int i = 0; i < parameterNames.length; i++) { paramMap.put(parameterNames[i], args[i]); } return paramMap; } /** * 返回数据 * * @param retVal * @return */ private String postHandle(Object retVal) { if (null == retVal) { return ""; } return JSON.toJSONString(retVal); } /** * 获取目标主机的ip * * @param request * @return */ private String getRemoteHost(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; } }
最近下载更多
iceboard LV2
2023年5月30日
wuchunfu LV4
2023年3月9日
落后就要挨打 LV26
2023年1月13日
1234mama LV19
2022年6月7日
君知否 LV17
2021年11月11日
mylzdy LV12
2021年10月11日
weixh7 LV25
2021年7月28日
唐僧肉01 LV8
2021年7月7日
kwm2921944 LV10
2021年5月26日
nt893120650 LV4
2021年5月12日
最近浏览更多
xianyu091012 LV4
11月18日
微信网友_7134912998903808 LV9
9月11日
TY0165 LV20
6月20日
漫步的海星 LV4
2023年9月26日
newhaijun LV15
2023年9月20日
www2222 LV2
2023年8月9日
601601lmy LV5
2023年7月19日
dapeng0011 LV15
2023年6月19日
iceboard LV2
2023年5月29日
1049066887 LV13
2023年4月24日