Web
層做爲服務的入口,對請求參數和響應結果的日誌記錄是必不可少的,本文結合AOP
切面技術,統一處理Web
日誌。java
大部分人,會直接在
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>
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
的實現說點什麼呢,有任何建議,歡迎留言探討,本文源碼。spring
歡迎關注博主公衆號,第一時間推送最新文章json