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