-
添加依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.8</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.8</version> </dependency>
- 注入spring容器
在配置文件中开启注解扫描。 <!-- 启动对@AspectJ注解的支持 --> <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller--> <aop:aspectj-autoproxy proxy-target-class="true"/>
<bean class="com.frame.web.cplat.aspect.ControllerLogAspect"></bean>
- 源码 注意aop的方法一定要有返回值。不然消息就会丢失到银河系
package com.frame.web.xx.aspect; import com.alibaba.fastjson.JSONObject; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ui.ModelMap; import org.springframework.validation.support.BindingAwareModelMap; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.Map; import java.util.UUID; /** * @Title: ControllerLogAspect * @Description: * @Auther:wangli * @Version: 1.0 * @create 2019-04-12 19:00 */ @Aspect public class ControllerLogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(ControllerLogAspect.class); // controller层的统计日志/耗时(方法所在的包) public static final String POINT = "execution(public * com.frame.web.xx.controller..*.*(..)))"; @Around(POINT) public Object around(ProceedingJoinPoint pjp) throws Throwable { //通过uuid关联请求参数和返回参数 String uuid = UUID.randomUUID().toString().replaceAll("-", ""); //开始时间一定要写在proceed之前 long startTime = System.currentTimeMillis(); Object proceed = pjp.proceed(); methodBefore(pjp, uuid); try { methodAfterReturing(proceed, uuid,startTime); } catch (Exception e) { LOGGER.error("[{}]Response异常内容:{}", uuid, e); throw e; } return proceed; } public void methodBefore(JoinPoint joinPoint, String uuid) { // 打印请求内容 try { // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); StringBuffer requestURL = request.getRequestURL(); String remoteAddr = request.getRemoteAddr(); String method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName(); LOGGER.info("\n------------------------------------------------\n"); LOGGER.info("[{}]请求URL : {}",uuid, requestURL); LOGGER.info("[{}]请求IP : {}",uuid, remoteAddr); LOGGER.info("[{}]请求方法 : {}",uuid, method); // 只记录post方法 if ("POST".equals(request.getMethod()) && "application/json".equals(request.getHeader("Content-Type"))) { String parms = ""; // 获取参数, 只取自定义的参数, 自带的HttpServletRequest, HttpServletResponse不管 if (joinPoint.getArgs().length > 0) { for (Object o : joinPoint.getArgs()) { if (o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingAwareModelMap||o instanceof ModelMap) { continue; } parms = JSONObject.toJSONString(o); LOGGER.info("[{}]请求参数 : {} ",uuid, parms); } } } else { LOGGER.info("[{}]请求参数 : {}",uuid,getParamString(request.getParameterMap())); LOGGER.info("\n"); } } catch (Exception e) { LOGGER.error("[{}]AOP methodBefore异常:{}", uuid, e); } } public void methodAfterReturing(Object o, String uuid,Long startTime) { try { if (o != null) { long endTime = System.currentTimeMillis(); LOGGER.info("[{}]接口耗时 :[{}]毫秒", uuid,(endTime-startTime)); LOGGER.info("[{}]返回参数 :\n{}", uuid, JSONObject.toJSON(o)); } } catch (Exception e) { LOGGER.error("[{}]AOP methodAfterReturing:", uuid, e); } } private String getParamString(Map<String, String[]> map) { StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String[]> e : map.entrySet()) { sb.append(e.getKey()).append("="); String[] value = e.getValue(); if (value != null && value.length == 1) { sb.append(value[0]).append("\t"); } else { sb.append(Arrays.toString(value)).append("\t"); } } return sb.toString(); } }
- 运行效果
20:42:17.901 [http-apr-8080-exec-6] INFO c.f.w.c.a.ControllerLogAspect - [1c7f36cd018d4b9da7dc105098df4400]请求URL : http://localhost:8080/bbox2-web-cplat/dyzh/estest/getEmployeeById 20:42:17.901 [http-apr-8080-exec-6] INFO c.f.w.c.a.ControllerLogAspect - [1c7f36cd018d4b9da7dc105098df4400]请求IP : 127.0.0.1 20:42:17.901 [http-apr-8080-exec-6] INFO c.f.w.c.a.ControllerLogAspect - [1c7f36cd018d4b9da7dc105098df4400]请求方法 : com.frame.web.cplat.controller.elasticsearch.ElasticSearchTest.getEmployeeById 20:42:17.920 [http-apr-8080-exec-6] INFO c.f.w.c.a.ControllerLogAspect - [1c7f36cd018d4b9da7dc105098df4400]请求参数 : {"id":"1"} 20:42:17.921 [http-apr-8080-exec-6] INFO c.f.w.c.a.ControllerLogAspect - [1c7f36cd018d4b9da7dc105098df4400]接口耗时 :[20]毫秒 20:42:17.921 [http-apr-8080-exec-6] INFO c.f.w.c.a.ControllerLogAspect - [1c7f36cd018d4b9da7dc105098df4400]返回参数 : {"addition":"","code":"200","id":"","message":"","object":{"about":"I love to go rock climbing","age":25,"first_name":"John","id":"1","interests":["sports","music"],"last_name":"Smith"},"remark":"","success":true,"time":"2019-04-15 20:42:17"}