struts2 過濾器和攔截器的區別和使用,struts2過濾器
java web 過濾器和攔截器的區別和使用
1.1 什麼是攔截器:
攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或欄位被訪問之前,進行攔截然後在之前或之後加入某些操作。攔截是AOP的一種實現策略。
在Webwork的中文文檔的解釋為——攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發人員可以定義在一個action執行的前後執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。
談到攔截器,還有一個詞大家應該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱為攔截器棧 Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序連接成一條鏈。在訪問被攔截的方法或欄位時,攔截器鏈中的攔截器就會按其之前定義的順序被調用。
1.2. 攔截器的實現原理:
大部分時候,攔截器方法都是通過代理的方式來調用的。Struts 2的攔截器實現相對簡單。當請求到達Struts 2的ServletDispatcher時,Struts 2會尋找設定檔,並根據其配置執行個體化相對的攔截器對象,然後串成一個列表(list),最後一個一個地調用列表中的攔截器。
1.3 什麼是過濾器
過濾器是一個程式,它先於與之相關的servlet或JSP頁面運行在伺服器上。過濾器可附加到一個或多個servlet或JSP頁面上,並且可以檢查進入這些資源的請求資訊。在這之後,過濾器可以作如下的選擇:
①以常規的方式調用資源(即,調用servlet或JSP頁面)。
②利用修改過的請求資訊調用資源。
③調用資源,但在發送響應到客戶機前對其進行修改。
④阻止該資源調用,代之以轉到其他的資源,返回一個特定的狀態碼或產生替換輸出。
1.4 Servlet過濾器的基本原理
在Servlet作為過濾器使用時,它可以對客戶的請求進行處理。處理完成後,它會交給下一個過濾器處理,這樣,客戶的請求在過濾鏈裡逐個處理,直到請求發送到目標為止。例如,某網站裡有提交“修改的註冊資訊”的網頁,當使用者填寫完修改資訊並提交後,伺服器在進行處理時需要做兩項工作:判斷用戶端的會話是否有效;對提交的資料進行統一編碼。這兩項工作可以在由兩個過濾器組成的過濾鏈裡進行處理。當過濾器處理成功後,把提交的資料發送到最終目標;如果過濾器處理不成功,將把視圖派發到指定的錯誤頁面。
2、攔截器與過濾器的區別 :
1. 攔截器是基於java的反射機制的,而過濾器是基於函數回調。
2. 攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
3. 攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。
4. 攔截器可以訪問action上下文、值棧裡的對象,而過濾器不能訪問。
5. 在action的生命週期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次
攔截器的代碼實現(以struts2為例):
1、在xml檔案中如何定義攔截器
<interceptors> <interceptor name="filterIPInterceptor" class="com.xxxx.web.FilterIPActionInterceptor" /><interceptor-stack name="filterIPStack"><interceptor-ref name="defaultStack" /> <interceptor-ref name="filterIPInterceptor" /></interceptor-stack></interceptors>
2、怎麼遍別寫自訂攔截器
public class FilterIPActionInterceptor extends AbstractInterceptor{ /** 日誌控制. */ private final Log log = LogFactory.getLog(getClass()); /** * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation) */ @Override @SuppressWarnings("unchecked") public String intercept(ActionInvocation invocation) throws Exception { String result = null; // 獲得當前方法名. String methodName = invocation.getInvocationContext().getName(); String currIp = null; try { if (invocation.getAction() instanceof PortletAction) { PortletAction action = (PortletAction) invocation.getAction(); currIp = action.getRequest().getRemoteAddr(); } String ip = ApplicationResource.getHotValue("ALLOW_CACHE_IP"); if (StringUtils.isBlank(ip) || StringUtils.isBlank(currIp)) { log.error("允許重新整理的IP不存在或當前請求的IP非法."); throw new NoAllowIPException(); } else { String[] ips = ip.split(","); boolean errorIp = true; for (String s : ips) { if (s.equals(currIp)) errorIp = false; } // 判斷IP if (errorIp) throw new NoAllowIPException(); } result = invocation.invoke();//調用被攔截的方法 } catch (Exception e) { log.error("異常類名:" + invocation.getAction().getClass()); log.error("異常方法:" + methodName, e); throw e; } return result; } }
3、怎麼編寫過濾器
1、在web.xml裡面配置自訂的攔截器
<filter><filter-name>Redirect Filter</filter-name><filter-class>com.xx.filter.RedirectFilter</filter-class></filter> <filter-mapping><filter-name>Redirect Filter</filter-name><url-pattern>/xx/xx/*</url-pattern> </filter-mapping> 2、如何編寫自訂的攔截器public class RedirectFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { // 擷取URL Long startTime = null; if (log.isDebugEnabled()) { startTime = System.currentTimeMillis(); } HttpServletRequest httpRequest = (HttpServletRequest) request; String url = httpRequest.getRequestURL().toString(); if (url == null || url.trim().length() == 0) { return; } if (url.indexOf(luceneCreateMapping) != -1 || url.indexOf(luceneSearchMapping) != -1) { doFilterForxxx(request, response, url); } else { doxxxx(request, response, url); } if (log.isDebugEnabled()) { long endTime = System.currentTimeMillis(); Thread currentThread = Thread.currentThread(); String threadName = currentThread.getName(); log.debug("[" + threadName + "]" + "< " + this.getClass().getName() + " " + url + " " + (endTime - startTime) + " ms"); }// 啟用下一個Filter filterChain.doFilter(request, response); }}
經本人親測,此程式完全正確,若有不同意見,請留言
資料來源:http://www.ylzx8.cn/web/web/993988.html