spring Aop+RequestContextHolder 注解实现日志打印

 

  1. 添加依赖<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>
    
    
    
  2. 注入spring容器 
    在配置文件中开启注解扫描。
    <!-- 启动对@AspectJ注解的支持 -->
    <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller-->
    <aop:aspectj-autoproxy proxy-target-class="true"/><bean class="com.frame.web.cplat.aspect.ControllerLogAspect"></bean>
  3. 源码    注意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();
                }
    }
    
  4. 运行效果
    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"}

     

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值