項目中需要監聽用戶具體的請求操作,便通過一個攔截器來監聽,並繼續相應的日志記錄
項目構建與Spring Boot,Spring Boot實現一個攔截器很容易。
Spring Boot的核心啟動類繼承WebMvcConfigurerAdapter
// 增加攔截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new RequestLog()); } //這個RequestLog就是我們定義的攔截器
攔截器的編寫
public class RequestLog extends HandlerInterceptorAdapter {
/**
* 前置檢查
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String ip = request.getRemoteAddr();
long startTime = System.currentTimeMillis();
request.setAttribute("requestStartTime", startTime);
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 獲取用戶token
Method method = handlerMethod.getMethod();
System.out.println("用戶:"+ip+",訪問目標:"+method.getDeclaringClass().getName() + "." + method.getName());
return true;
}
// controller處理完成
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
long startTime = (Long) request.getAttribute("requestStartTime");
long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime;
// log it
if (executeTime > 1000) {
System.out.println("[" + method.getDeclaringClass().getName() + "." + method.getName() + "] 執行耗時 : "
+ executeTime + "ms");
} else {
System.out.println("[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "] 執行耗時 : "
+ executeTime + "ms");
}
}
}
我們自己實現的攔截器需要繼承HandlerInterceptorAdapter,並重寫如下三個方法:
在preHandle中,可以進行編碼、安全控制等處理; 在postHandle中,有機會修改ModelAndView;
還存在一個也比較重要的方法在afterCompletion中,下面介紹一些這三個方法的執行流程:
發起請求,進入攔截器鏈,運行所有攔截器的preHandle方法.
當preHandle方法返回false時,(后面的攔截器就不再執行了)從當前攔截器往回執行所有攔截器的afterCompletion方法(不是postHandle方法哦),再退出攔截器鏈。
當preHandle方法全為true時,執行下一個攔截器,直到所有攔截器執行完。再運行被攔截的Controller。然后進入攔截器鏈,運行所有攔截器的postHandle方法,完后從最后一個攔截器往回執行所有攔截器的afterCompletion方法.
當有攔截器拋出異常時,會從當前攔截器往回執行所有攔截器的afterCompletion方法
preHandle方法:
返回true,映射處理器執行鏈將繼續執行;
當返回false時,DispatcherServlet處理器認為攔截器已經處理完了請求(這個請求已經被攔截了:http請求的status是200,但response什么也沒有),而不繼續執行執行鏈中的其它攔截器和處理器。
http://www.itdadao.com/articles/c15a591762p0.html