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; } }