zoukankan      html  css  js  c++  java
  • SpringBoot中切点实现请求和返回数据的打印

    1.定义切点

    1.1 类上面加上下方注解

    @Aspect // 定义一个切面
    @Configuration //配置类
    

    1.2 指定切点位置

     @Pointcut("execution(* com.example.demo.controller..*Controller.*(..))")
        public void excudeService() {
        }
    

    其中execution表达式可以自行扩展.

    此处表示com.example.demo.controller包及其子包中所有以Controller结尾的类中的所有方法.

    简单扩展

    execution(* com.example.demo.controller..Controller.(..))

    • controller后有两个点

      表示本身及其子包,改为一个点,则只表示当前包下

    • *Controller

      以Controller结尾

    2.切点实现

    上方定义了实现方法excudeService()

    2.1 方法上加上注解

     	// 切点实现
        @Around("excudeService()")
    	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        }
    

    2.2 编写具体代码

    写完你不用启动项目,idea就会帮你推断哪些地方会使用上.

    image-20210817200359385

    3.参考代码

    package com.example.demo.config;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Map;
    
    /**
     * @Description: 切面实现 controller请求与返回数据的打印
     * @Class: LogRecordAspect
     * @Author: Yiang37
     * @Date: 2021/8/6 11:40
     * @Version: 1.0
     */
    @Configuration
    @Aspect // 定义一个切面
    @Slf4j //代码直接写log.xx即可
    public class LogRecordAspect {
        // 定义切点
        @Pointcut("execution(* com.example.demo.controller..*Controller.*(..))")
        public void excudeService() {
        }
    
        // 切点实现
        @Around("excudeService()")
        public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
            log.info("----------------------------------------------------");
            // 1.请求处理
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
            assert servletRequestAttributes != null;
            HttpServletRequest request = servletRequestAttributes.getRequest();
            String uri = request.getRequestURI();
            // 获取请求方式
            String method = request.getMethod();
            // GET
            if ("GET".equals(method)) {
                StringBuilder stringBuilder = new StringBuilder();
                // request.getParameterMap()只能获取Get方式传入的数据
                Map<String, String[]> parameterMap = request.getParameterMap();
                for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                    stringBuilder.append(entry.getKey()).append(" - ").append(Arrays.toString(entry.getValue())).append("
    ");
                }
                // 去掉最后一个多余的回车符
                stringBuilder.deleteCharAt(stringBuilder.length()-1);
                log.info(">> | 请求开始,URI: '{}', method: '{}', Data:
    {}", uri, method, stringBuilder);
            }
            // POST
            if ("POST".equals(method)) {
                try (BufferedReader bufferedReader = new BufferedReader(request.getReader())) {
                    // 每次读取一行
                    StringBuilder stringBuilder = new StringBuilder();
                    String str;
                    while ((str = bufferedReader.readLine()) != null) {
                        stringBuilder.append(str);
                    }
                    // 美化下stringBuilder这个json字符串的格式
                    String prettyJsonStr = JSON.toJSONString(JSONObject.parseObject(stringBuilder.toString()), SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
                    log.info(">> | 请求开始,URI: '{}', method: '{}', Data:
    {}", uri, method, prettyJsonStr);
                } catch (IOException e) {
                    log.error("Post参数请求解析失败:{}", e.getMessage());
                }
            }
    
            // 2.返回处理
            Object result = pjp.proceed();
            log.info("<< | 请求结束,controller返回值:
    " + JSON.toJSON(result));
            log.info("----------------------------------------------------");
            return result;
        }
    }
    

    4.相关pom包

    <!-- aop -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    
    <!-- log4j2 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    
    <!-- fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
    
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    

    日志相关使用可以看我这篇文章:

    Springboot中slf4j+log4j2的使用

  • 相关阅读:
    我心中的核心组件(可插拔的AOP)~第十三回 实现AOP的拦截组件Unity.Interception
    .NET 使用unity实现依赖注入
    AOP技术基础
    PowerShell 远程管理之 about_Remote_Troubleshooting
    PowerShell远程连接主机进行会话
    PowerShell_零基础自学课程_9_高级主题:静态类和类的操作
    PowerShell_零基础自学课程_8_高级主题:WMI对象和COM组件
    PowerShell 中的目录文件管理
    解决360浏览器兼容模式不兼容,极速模式兼容问题
    reportng之测试报告升级美化
  • 原文地址:https://www.cnblogs.com/yang37/p/15153970.html
Copyright © 2011-2022 走看看