Java基础|spring/spring boot 自定义日志注解输出请求参数和结果

本文是基于AspectJ静态代理模式 1.maven添加依赖jar包

org.aspectj aspectjweaver 1.8.13

2.定义log注解类
import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LoggerManage {/** * 说明 * @return */ public String description(); }

3.创建日志切面类
@Aspect @Component public class LoggerAdvice {private Logger logger = LoggerFactory.getLogger(getClass()); /** * 在这里定义切面的点,Pointcut的表达式语法需要匹配到你调用的方法中 */ @Pointcut("within(cn.hlvan.citywide.controller..*)") public void declareJoinPointExpression() { }@Before("declareJoinPointExpression()") public void addBeforeLogger(JoinPoint joinPoint) { try { RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest(); String url = request.getRequestURL().toString(); String method = request.getMethod(); String uri = request.getRequestURI(); String userAgent = request.getHeader("User-Agent"); Cookie cookie = null; Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie c : cookies) { if (c.getName().endsWith("Token")) { cookie = c; break; } } } String CookieString=cookie==null?"":GsonUtils.getInstance().toJson(cookie); String params = GsonUtils.toJson(request.getParameterMap()); String apiName = ""; String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); for (Method m : methods) { if (m.getName().equals(methodName)) { Class[] clazzs = m.getParameterTypes(); if (clazzs.length == arguments.length) { if (m.getDeclaredAnnotation(LoggerManage.class) != null) { apiName = m.getDeclaredAnnotation(LoggerManage.class).description(); break; } } } } logger.info("apiName:{}, url: {},uri: {}, method: {}, params: {},Cookie:{},UserAgent:{}", apiName,url,uri, method, params, CookieString,userAgent); } catch (ClassNotFoundException e) { e.printStackTrace(); } }//@AfterReturning(value = "https://www.it610.com/article/declareJoinPointExpression()", returning = "returnObj") //public void addAfterReturningLogger(JoinPoint joinPoint, Object returnObj) { //System.out.println("结束"); //}//@AfterThrowing(pointcut = "declareJoinPointExpression()", throwing = "ex") //public void addAfterThrowingLogger(JoinPoint joinPoint, Exception ex) { //System.out.println("异常"); //} @Around(value = "https://www.it610.com/article/declareJoinPointExpression()") public Object doAround(ProceedingJoinPoint proceeding) throws Throwable { long beforeTime=System.currentTimeMillis(); //执行被拦截的方法 result是返回结果 Object result = proceeding.proceed(); //debug模式下才计算方法耗时 if (logger.isDebugEnabled()) { long afterTime=System.currentTimeMillis(); RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest(); logger.info("请求:{} , 耗时:{}ms",request.getRequestURI(),afterTime-beforeTime); } //此处可以在log输出result,依据业务要求处理 return result; } }

4.在Controller中注解的使用
@LoggerManage(description = "app检查升级") @GetMapping("/check_update") public String checkUpdate() { return "ok"; }

5.调用后的打印信息
apiName:app检查升级, url: http://localhost:8888/check_update , uri: /check_update, method: GET, params: {},Cookie:{"name":"xxxx","value":"XXXX","version":0,"maxAge":-1,"secure":false,"httpOnly":false},UserAgent:XXXX ... ... ... 请求:/driver/check_update , 耗时:953ms

6.其他说明(可以忽略) 如果使用springboot 1.在maven中添加 org.springframework.boot spring-boot-starter-aop 2.将LoggerAdvice上的@Component注解换成@Configuration 以上两步操作只是更加符合springboot标准,不替换功能也一样。





【Java基础|spring/spring boot 自定义日志注解输出请求参数和结果】





    推荐阅读