1.添加依赖
通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency
2. 自定义注解类 LogRequest
/** * @ClassNameLogRequest.java * @author shengwu * @date 2019-10-19 * @Target 此注解的作用目标,括号里METHOD的意思说明此注解只能加在方法上面 * @Retention 注解的保留位置,括号里RUNTIME的意思说明注解可以存在于运行时,可以用于反射 * @Documented 说明该注解将包含在javadoc中 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LogRequest { /** * 是否记录日志表中 * @return */ String logFlag() default "N"; /** * 接口名称 * @return */ String interfaceName() default ""; }
3. 切面类
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * 此类为一个切面类,主要作用就是对接口的请求进行拦截 * 拦截的方式,只需要在指定接口方法上面加上@LogRequest注解即可 * * @author shengwu * @version 1.0 * @since 2019/09/28 */ @Aspect @Component public class RequestAspect { private static final Logger logger = LoggerFactory.getLogger(RequestAspect.class); @Autowired private IInterfaceLogService iInterfaceLogService; /** * 表示在执行被@LogRequest注解修饰的方法之前 会执行doBefore()方法 * * @param joinPoint 连接点,就是被拦截点 */ @Around(value = "@annotation(LogRequest)") public Object doAround(ProceedingJoinPoint joinPoint, LogRequest LogRequest) throws Throwable { Long start = System.currentTimeMillis(); try { Object result = joinPoint.proceed(); this.methodAround(joinPoint,result,start,LogRequest.logFlag(),LogRequest.interfaceName(),true); return result; } catch (Throwable throwable) { throwable.printStackTrace(); this.methodAround(joinPoint,throwable.getMessage(),start,LogRequest.logFlag(),LogRequest.interfaceName(),false); throw throwable; } } }
4. 日志方法
/** * * @param joinPoint * @param object 返回对象值 * @param startTime 方法开始时间 * @param logFlag 是否插入日志 * @param requestStatus 本次请求状态 * */ public void methodAround(JoinPoint joinPoint,Object object,Long startTime,String logFlag,String interfaceName,Boolean requestStatus) { //获取到请求的属性 ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); //获取到请求对象 HttpServletRequest request = attributes.getRequest(); //URL:根据请求对象拿到访问的地址 logger.info("url={}" , request.getRequestURL()); logger.info("接口名称={}" , interfaceName); logger.info("代理对象自己:{}" + joinPoint.getThis()); //获取传入目标方法的参数 Object[] args = joinPoint.getArgs(); Long time = (System.currentTimeMillis()-startTime); logger.info("执行时间长{}",time); Long endTime = System.currentTimeMillis(); Date date = new Date(startTime); InterfaceLogDTO interfaceLogDTO = new InterfaceLogDTO(); String uuid = UUID.randomUUID().toString(); interfaceLogDTO.setInvokeKey(uuid); //微服务应用名 interfaceLogDTO.setServerCode(serverCode); interfaceLogDTO.setRequestTime(date); interfaceLogDTO.setInterfaceResponseTime(endTime-startTime); interfaceLogDTO.setServerName(interfaceName); interfaceLogDTO.setApplicationCode(applicationInitListener.getServerIpPort()); interfaceLogDTO.setUserAgent(request.getHeader("user-agent")); CustomUserDetails customClient = DetailsHelper.getUserDetails(); if (customClient==null||customClient.getOrganizationId()==null) { logger.error("接口"+interfaceName+"租户获取空"); return; } interfaceLogDTO.setTenantId(customClient.getOrganizationId()); interfaceLogDTO.setClientId(customClient.getClientId()==null?null:String.valueOf(customClient.getClientId())); interfaceLogDTO.setInterfaceUrl(request.getRequestURL().toString()); interfaceLogDTO.setRequestMethod(request.getMethod()); interfaceLogDTO.setIp(request.getRemoteAddr()); interfaceLogDTO.setInterfaceRequestTime(date); //明细 InterfaceLogDtlDTO interfaceLogDtlDTO = new InterfaceLogDtlDTO(); interfaceLogDTO.setInterfaceLogDtlDTO(interfaceLogDtlDTO); interfaceLogDtlDTO.setInvokeKey(uuid); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < args.length; i++) { try { stringBuilder.append(objectMapper.writeValueAsString(args[i])); } catch (JsonProcessingException e) { e.printStackTrace(); } } interfaceLogDtlDTO.setInterfaceReqBodyParam(stringBuilder.toString()); String interfaceRespContent =null; try { if (result!=null) { //返回内容 interfaceRespContent = objectMapper.writeValueAsString(result); } } catch (JsonProcessingException e) { e.printStackTrace(); } if (requestStatus){ interfaceLogDtlDTO.setInterfaceRespContent(interfaceRespContent); interfaceLogDTO.setResponseStatus(SUCCESS); interfaceLogDTO.setInterfaceResponseStatus(SUCCESS); } if (!requestStatus){ interfaceLogDtlDTO.setStacktrace(interfaceRespContent); interfaceLogDTO.setResponseStatus(FAIL); interfaceLogDTO.setInterfaceResponseStatus(FAIL); } if(!FLAG_Y.equals(logFlag)){ logger.info("出站信息{}",interfaceLogDTO.toString()); return; } }