SpringBoot基礎教程2-1-6 日誌規範-使用AOP統一處理Web日誌

1. 概述

Web層做爲服務的入口,對請求參數和響應結果的日誌記錄是必不可少的,本文結合AOP切面技術,統一處理Web日誌。java

2. 通常Web日誌記錄方法

大部分人,會直接在Controller打印日誌,以下:git

@Slf4j
@RestController
public class UserController {
    @PostMapping("/user")
    public R addUser(@RequestBody User user){
        log.info("user: {}", JSON.toJSONString(user));
        R r = R.isOk().data(user);
        log.info("result: {}", JSON.toJSONString(user));
        return r;
    }
}

這種寫法,致使日誌代碼重複,而且耦合在Controller層,不夠優雅,也不夠偷懶。github

  • JSON類是fastjson的工具類,推薦使用
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.39</version>
</dependency>

3. 優雅的記錄web日誌

  • pom文件,引入AOP依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  • 簡單建立Controller
@RestController
@RequestMapping("/log")
public class AopLogController {

    @PostMapping("/user")
    public R addUser(@RequestBody User user){

        return R.isOk().data(user);
    }
}
  • 建立日誌切面
@Slf4j
@Aspect
@Component
public class WebLogAspect {
    @Pointcut("execution(public * com.mkeeper.controller.logging..*.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint){
        // 接收到請求,記錄請求內容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 記錄下請求內容
        log.info("<<<<<<<<<<<<<<<<<<<<<<<<");
        log.info("URL : " + request.getRequestURL().toString());
        log.info("HTTP_METHOD : " + request.getMethod());
        log.info("IP : " + request.getRemoteAddr());
        log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));

    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret){
        // 處理完請求,返回內容
        log.info("RESPONSE : " + ret);
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>");
    }
}

@Aspect將一個java類定義爲切面類 @Pointcut定義一個切入點,能夠是一個規則表達式,好比下例中某個package下的全部函數,也能夠是一個註解等。 @Before在切入點開始處切入內容 @After在切入點結尾處切入內容 @AfterReturning在切入點return內容以後切入內容(能夠用來對處理返回值作一些加工處理) @Around在切入點先後切入內容,並本身控制什麼時候執行切入點自身的內容 @AfterThrowing用來處理當切入內容部分拋出異常以後的處理邏輯web

  • 其餘基礎類能夠看源碼
  • 注意:若是須要CGLIB來實現AOP的時候,須要配置spring.aop.proxy-target-class=true,否則默認使用的是標準Java的實現

4. 測試結果

5. 工程目錄

6. 結束語

說點什麼呢,有任何建議,歡迎留言探討,本文源碼spring


歡迎關注博主公衆號,第一時間推送最新文章json

歡迎關注博主公衆號

相關文章
相關標籤/搜索