Java interceptor 攔截器
一:攔截器的應用場景
1、日誌記錄:記錄請求資訊的日誌,以便進行資訊監控、資訊統計、計算PV(Page VIEW)等。
2、許可權檢查:如登入檢測,進入處理器檢測檢測是否登入,如果沒有直接返回到登入頁面;
3、效能監控:有時候系統在某段時間莫名其妙的慢,可以透過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如apache可以自動記錄);
4、通用行為:讀取cookie得到使用者資訊並將使用者物件放入請求,從而方便後續流程使用,還有如提取Locale、Theme資訊等,只要是多個處理器都需要的即可使用攔截器實現。
5、OpenSessionInView:如Hibernate,在進入處理器開啟SESSION,在完成後關閉SESSION。
二:攔截器與過濾器的區別
1、攔截器是基於Java的反射機制的,而過濾器是基於函式回撥。
2、攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
3、攔截器只能對ACTION請求起作用,而過濾器則可以對幾乎所有的請求起作用。
4、攔截器可以訪問ACTION上下文、值棧裡的物件,而過濾器不能訪問。
5、在ACTION的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次。
6、攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器裡注入一個service,可以呼叫業務邏輯。
三:攔截器的實現
1.過濾器是JavaEE標準,採用函式回撥的方式進行。是在請求進入容器之後,還未進入Servlet之前進行預處理,並且在請求結束返回給前端這之間進行後期處理。
chain.doFilter(request, response);這個方法的呼叫作為分水嶺。事實上呼叫Servlet的doService()方法是在chain.doFilter(request, response);這個方法中進行的。
2.攔截器是被包裹在過濾器之中的。
a.preHandle()這個方法是在過濾器的chain.doFilter(request, response)方法的前一步執行,也就是在 [System.out.println("before...")][chain.doFilter(request, response)]之間執行。
b.preHandle()方法之後,在RETURN ModelAndView之前進行,可以操控Controller的ModelAndView內容。
c.afterCompletion()方法是在過濾器返回給前端前一步執行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之間執行。
四:SpringMvc 攔截器和過濾器執行流程
五:例項
1、日誌記錄:記錄請求資訊的日誌,以便進行資訊監控、資訊統計、計算PV(Page VIEW)等。
2、許可權檢查:如登入檢測,進入處理器檢測檢測是否登入,如果沒有直接返回到登入頁面;
3、效能監控:有時候系統在某段時間莫名其妙的慢,可以透過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如apache可以自動記錄);
4、通用行為:讀取cookie得到使用者資訊並將使用者物件放入請求,從而方便後續流程使用,還有如提取Locale、Theme資訊等,只要是多個處理器都需要的即可使用攔截器實現。
5、OpenSessionInView:如Hibernate,在進入處理器開啟SESSION,在完成後關閉SESSION。
二:攔截器與過濾器的區別
1、攔截器是基於Java的反射機制的,而過濾器是基於函式回撥。
2、攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
3、攔截器只能對ACTION請求起作用,而過濾器則可以對幾乎所有的請求起作用。
4、攔截器可以訪問ACTION上下文、值棧裡的物件,而過濾器不能訪問。
5、在ACTION的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次。
6、攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器裡注入一個service,可以呼叫業務邏輯。
三:攔截器的實現
1.過濾器是JavaEE標準,採用函式回撥的方式進行。是在請求進入容器之後,還未進入Servlet之前進行預處理,並且在請求結束返回給前端這之間進行後期處理。
點選(此處)摺疊或開啟
-
@Override
-
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-
System.out.println("before...");
-
chain.doFilter(request, response);
-
System.out.println("after...");
- }
2.攔截器是被包裹在過濾器之中的。
點選(此處)摺疊或開啟
-
@Override
-
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-
System.out.println("preHandle");
-
return true;
-
}
-
-
@Override
-
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
-
System.out.println("postHandle");
-
}
-
-
@Override
-
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
-
System.out.println("afterCompletion");
- }
b.preHandle()方法之後,在RETURN ModelAndView之前進行,可以操控Controller的ModelAndView內容。
c.afterCompletion()方法是在過濾器返回給前端前一步執行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之間執行。
四:SpringMvc 攔截器和過濾器執行流程
五:例項
點選(此處)摺疊或開啟
-
public class SystemAccessInterceper extends HandlerInterceptorAdapter {
-
-
private final String checkpointName = "DO_CHECKPOINT";
-
private final String shareType = "enjoylink_share";
-
String[] noFilters = ConfigureUtil.getStringArray("nofilter.urls");
-
-
private final Logger logger = Logger.getLogger(getClass());
-
-
@Override
-
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
-
throws Exception {
-
String userAgent = request.getHeader("user-agent");
-
userAgent = StringUtils.startsWith(userAgent, Constants.USER_AGENT) ? userAgent
-
: request.getHeader("x-user-agent");
-
String type = request.getParameter("shareType");
-
String requestUri = request.getRequestURI();
-
if (isFilter(requestUri)) {
-
return true;
-
}
-
logger.info("User-Agent:" + userAgent);
-
if (!StringUtils.equalsIgnoreCase(shareType, type) && (!StringUtils.startsWith(userAgent, Constants.USER_AGENT)
-
|| 2 > StringUtils.indexOfAny(userAgent, "|"))) {
-
logger.info("非法請求介面!!");
-
return false;
-
}
-
-
try {
-
if (StringUtils.contains(userAgent, "|")) {
-
String[] agts = userAgent.split("\\|");
-
request.setAttribute(Constants.HEAD_SYS, agts[1]);
-
request.setAttribute(Constants.HEAD_VERSION, agts[2]);
-
}
-
request.setAttribute(Constants.LOG_ACCESS_TIME, System.currentTimeMillis());
-
return super.preHandle(request, response, handler);
-
}
-
catch (Exception e) {
-
logger.error("攔截器驗證失敗!", e);
-
return false;
-
}
-
}
-
-
/**
-
* TODO: 檢查是否需要過濾
-
*
-
* @param uri
-
* @return
-
*/
-
private boolean isFilter(String uri) {
-
if (org.apache.commons.lang3.ArrayUtils.isEmpty(noFilters)) {
-
return Boolean.TRUE;
-
}
-
-
for (String noFilter : noFilters) {
-
if (StringUtils.contains(uri, noFilter)) {
-
return Boolean.TRUE;
-
}
-
}
-
-
return Boolean.FALSE;
-
}
-
-
@Override
-
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
-
throws Exception {
-
super.afterCompletion(request, response, handler, ex);
-
Object obj = request.getAttribute(Constants.LOG_ACCESS_TIME);
-
if (null != obj) {
-
Object rb = request.getAttribute(Constants.RETURN_BODY);
-
long accessTime = (long) obj;
-
if (null == rb || StringUtils.isEmpty(rb.toString())) {
-
logger.info("不進行檢查點處理!");
-
logger.info("處理請求" + request.getRequestURI() +"耗時"+ (System.currentTimeMillis() - accessTime) + "毫秒!");
-
return;
-
}
-
Object userId = request.getAttribute(Constants.REQUEST_USERID);
-
String system = request.getAttribute(Constants.HEAD_SYS).toString();
-
String version = request.getAttribute(Constants.HEAD_VERSION).toString();
-
-
logger.warn("處理請求|" + ((null == userId || "".equals(userId.toString())) ? "0" : userId.toString()) + "|"
-
+ system + "|" + version + "|" + request.getRequestURI() + "|"
-
+ GbdDateUtils.format(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm:ss") + "|"
-
+ (System.currentTimeMillis() - accessTime) + "|毫秒!");
-
try {
-
HandlerMethod handlerMethod = (HandlerMethod) handler;
-
BusinessCheckPoint checkPoint = handlerMethod.getMethodAnnotation(BusinessCheckPoint.class);
-
if (null != checkPoint) {
-
String checkpointKey = checkPoint.checkName();
-
-
// 業務處理結果為正確時。傳送積分或者信用累積
-
if (null != rb && null != userId && StringUtils.isNotEmpty(userId.toString())) {
-
ReturnBody returnBody = (ReturnBody) rb;
-
// 檢查點檢測,如果是檢查點則傳送訊息
-
if (returnBody.getCode() > 0) {
-
// 傳送檢查點訊息
-
CodeDesc codeDesc = new CodeDesc();
-
codeDesc.setJmsType(checkpointName);
-
codeDesc.setName(checkpointKey);
-
codeDesc.setBusinessCode(returnBody.getCheckpointCode());
-
codeDesc.setUserId(Integer.valueOf(userId.toString()));
-
JmsUtil.pushToUserQueue(codeDesc);
-
}
-
}
-
}
-
}
-
catch (Exception e) {
-
logger.error("傳送積分訊息失敗!", e);
-
}
-
}
-
}
-
- }
點選(此處)摺疊或開啟
-
<!-- 攔截器配置 -->
-
<mvc:interceptors>
-
<bean class="com.gemdale.ghome.business.intercepter.SystemAccessInterceper" />
- </mvc:interceptors>
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-2130071/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mybatis Interceptor 攔截器MyBatis
- 攔截器(Interceptor)與過濾器(Filter)過濾器Filter
- SpringMVC中使用Interceptor攔截器SpringMVC
- Okhttp的Interceptor攔截器原始碼解析HTTP原始碼
- gRPC(六)進階:攔截器 interceptorRPC
- SpringMVC中的攔截器Interceptor實現SpringMVC
- 過濾器 Filter 與 攔截器 Interceptor 的區別過濾器Filter
- 通過攔截器Interceptor優化Mybatis的in查詢優化MyBatis
- OkHttp 3.x 原始碼解析之Interceptor 攔截器HTTP原始碼
- Solon 的過濾器 Filter 和兩種攔截器 Handler、 Interceptor過濾器Filter
- 解決在Interceptor攔截器中使用@DubboReference注入為nullNull
- 攔截器,攔截器棧總結
- Java實現的攔截器Java
- Java Struts 實現攔截器Java
- 關於 SAP Spartacus Angular HTTP Interceptor 的攔截順序AngularHTTP
- MyBatis攔截器MyBatis
- Mybatis 攔截器MyBatis
- sql攔截器SQL
- Spring MVC 中的攔截器的使用“攔截器基本配置” 和 “攔截器高階配置”SpringMVC
- Angular 使用 Interceptor (攔截器) 請求新增 token 並統一處理 API 錯誤AngularAPI
- SpringMVC攔截器,設定不攔截的URLSpringMVC
- axios攔截器iOS
- axios 攔截器iOS
- spring攔截器Spring
- SpringMVC攔截器SpringMVC
- Spring-cloud學習筆記---Ribbon原始碼剖析之攔截器Interceptor方法SpringCloud筆記原始碼
- vue中用axios攔截器攔截請求和響應VueiOS
- Flume內建攔截器與自定義攔截器(程式碼實戰)
- 使用 Angular HTTP_INTERCEPTOR 攔截器來記錄超時請求的一些思考AngularHTTP
- Java後臺開發學習(2)——攔截器Java
- SpringMVC-攔截器SpringMVC
- 攔截過濾器模式過濾器模式
- gRPC(3):攔截器RPC
- 【SpringMVC】 4.3 攔截器SpringMVC
- web api新增攔截器WebAPI
- spring boot 攔截器Spring Boot
- SpringMVC配置攔截器SpringMVC
- Mybatis中的攔截器MyBatis