[轉]spring boot 攔截器 或 Spring AOP 方式記錄請求日誌
阿新 • • 發佈:2018-12-10
選擇使用攔截器實現,在實現中遇到兩個個問題:
a. POST請求 @RequestBody 傳的引數不知怎麼獲取?
b. 返回結果如何獲取?
c.攔截器中service 無法注入;(已解決)
不知道有沒有人遇到這種情況,攔截器沒有解決上述問題,後來使用 spring AOP 處理。
《一》攔截器方式
@Configuration public class OptPermissionHandlerInterceptor extends HandlerInterceptorAdapter { private Logger logger = LoggerFactory.getLogger(OptPermissionHandlerInterceptor.class); @Autowired private OptLogService optLogService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { } @SuppressWarnings("rawtypes") @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { try { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; String beanName = handlerMethod.getBean().getClass().toString(); String methodName = handlerMethod.getMethod().getName(); String uri = request.getRequestURI(); String remoteAddr = getIpAddr(request); String sessionId = request.getSession().getId(); String user = (String) request.getSession().getAttribute(Constant.USER); String method = request.getMethod(); System.out.println("請求方式為="+method); Map params = null; if("POST".equals(method)){ //........ }else{ params = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); } // 取不到值 MethodParameter[] mps = ((HandlerMethod) handler).getMethodParameters(); for(MethodParameter mp : mps){ System.out.println(mp.getParameterName() + " -- "+ mp.getParameterType()); } // 取不到值 Map<String, String[]> params2 = request.getParameterMap(); //攔截器中optLogService 沒有注入成功時,重新獲取; if (optLogService == null) { System.out.println("optLogService is null !!!"); BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext()); optLogService = (OptLogService) factory.getBean("optLogService"); } optLogService.saveOptLog(.....); } } catch (Exception e) { logger.error("使用者操作日誌記錄異常", e); } super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } //獲取客戶端IP private String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }
《二》Spring AOP方式(面向切面)
1.在pom.xml 中引入spring aop 依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.在 application.properties 檔案中新增:
spring.aop.auto=true
spring.aop.proxy-target-class=false
3.實現切面
@Aspect @Component public class WebRequestLogAspect { private static Logger logger = LoggerFactory.getLogger(WebRequestLogAspect.class); private ThreadLocal<OperatorLog> tlocal = new ThreadLocal<OperatorLog>(); @Autowired private OptLogService optLogService; @Pointcut("execution(public * com.whitelover.test..*.create*(..))") public void webRequestLog() {} // @Order(5) @Before("webRequestLog()") public void doBefore(JoinPoint joinPoint) { try { long beginTime = System.currentTimeMillis(); // 接收到請求,記錄請求內容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String beanName = joinPoint.getSignature().getDeclaringTypeName(); String methodName = joinPoint.getSignature().getName(); String uri = request.getRequestURI(); String remoteAddr = getIpAddr(request); String sessionId = request.getSession().getId(); String user = (String) request.getSession().getAttribute("user"); String method = request.getMethod(); String params = ""; if ("POST".equals(method)) { Object[] paramsArray = joinPoint.getArgs(); params = argsArrayToString(paramsArray); } else { Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); params = paramsMap.toString(); } logger.debug("uri=" + uri + "; beanName=" + beanName + "; remoteAddr=" + remoteAddr + "; user=" + user + "; methodName=" + methodName + "; params=" + params); OperatorLog optLog = new OperatorLog(); optLog.setBeanName(beanName); optLog.setCurUser(user); optLog.setMethodName(methodName); optLog.setParams(params != null ? params.toString() : ""); optLog.setRemoteAddr(remoteAddr); optLog.setSessionId(sessionId); optLog.setUri(uri); optLog.setRequestTime(beginTime); tlocal.set(optLog); } catch (Exception e) { logger.error("***操作請求日誌記錄失敗doBefore()***", e); } } // @Order(5) @AfterReturning(returning = "result", pointcut = "webRequestLog()") public void doAfterReturning(Object result) { try { // 處理完請求,返回內容 OperatorLog optLog = tlocal.get(); optLog.setResult(result.toString()); long beginTime = optLog.getRequestTime(); long requestTime = (System.currentTimeMillis() - beginTime) / 1000; optLog.setRequestTime(requestTime); System.out.println("請求耗時:" + optLog.getRequestTime() + optLog.getUri() + " ** " + optLog.getParams() + " ** " + optLog.getMethodName()); System.out.println("RESPONSE : " + result); optLogService.saveLog(optLog); } catch (Exception e) { logger.error("***操作請求日誌記錄失敗doAfterReturning()***", e); } } /** * 獲取登入使用者遠端主機ip地址 * * @param request * @return */ private String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } /** * 請求引數拼裝 * * @param paramsArray * @return */ private String argsArrayToString(Object[] paramsArray) { String params = ""; if (paramsArray != null && paramsArray.length > 0) { for (int i = 0; i < paramsArray.length; i++) { Object jsonObj = JSON.toJSON(paramsArray[i]); params += jsonObj.toString() + " "; } } return params.trim(); } }
spring aop參考網站:
http://blog.didispace.com/springbootaoplog/
@PointCut 表示式參考網站:
http://www.cnblogs.com/lic309/p/4079194.html