首頁>Club>
5
回覆列表
  • 1 # 使用者51050908467

    1,攔截器的概念

    java裡的攔截器是動態攔截Action呼叫的物件,它提供了一種機制可以使開發者在一個Action執行的前後執行一段程式碼,也可以在一個Action

    執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分程式碼的方式。在AOP中,攔截器用於在某個方法或者欄位被訪問之前,進行攔截

    然後再之前或者之後加入某些操作。目前,我們需要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道即可。

    2,攔截器的原理

    大部分時候,攔截器方法都是透過代理的方式來呼叫的。Struts2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2

    會查詢配置檔案,並根據配置例項化相對的攔截器物件,然後串成一個列表(List),最後一個一個的呼叫列表中的攔截器。Struts2的攔截器是可

    插拔的,攔截器是AOP的一個實現。Struts2攔截器棧就是將攔截器按一定的順序連線成一條鏈。在訪問被攔截的方法或者欄位時,Struts2攔截器鏈

    中的攔截器就會按照之前定義的順序進行呼叫。

    3,自定義攔截器的步驟

    第一步:自定義一個實現了Interceptor介面的類,或者繼承抽象類AbstractInterceptor。

    第二步:在配置檔案中註冊定義的攔截器。

    第三步:在需要使用Action中引用上述定義的攔截器,為了方便也可以將攔截器定義為預設的攔截器,這樣在不加特殊說明的情況下,所有的

    Action都被這個攔截器攔截。

  • 2 # 慎談奧秘

    1,攔截器的概念 java裡的攔截器是動態攔截Action呼叫的物件,它提供了一種機制可以使開發者在一個Action執行的前後執行一段程式碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分程式碼的方式。在AOP中,攔截器用於在某個方法或者欄位被訪問之前,進行攔截然後再之前或者之後加入某些操作。目前,我們需要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道即可。2,攔截器的原理 大部分時候,攔截器方法都是透過代理的方式來呼叫的。Struts2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2會查詢配置檔案,並根據配置例項化相對的攔截器物件,然後串成一個列表(List),最後一個一個的呼叫列表中的攔截器。Struts2的攔截器是可插拔的,攔截器是AOP的一個實現。Struts2攔截器棧就是將攔截器按一定的順序連線成一條鏈。在訪問被攔截的方法或者欄位時,Struts2攔截器鏈中的攔截器就會按照之前定義的順序進行呼叫。3,自定義攔截器的步驟 第一步:自定義一個實現了Interceptor介面的類,或者繼承抽象類AbstractInterceptor。 第二步:在配置檔案中註冊定義的攔截器。 第三步:在需要使用Action中引用上述定義的攔截器,為了方便也可以將攔截器定義為預設的攔截器,這樣在不加特殊說明的情況下,所有的Action都被這個攔截器攔截。4,過濾器與攔截器的區別 過濾器可以簡單的理解為“取你所想取”,過濾器關注的是web請求;攔截器可以簡單的理解為“拒你所想拒”,攔截器關注的是方法呼叫,比如攔截敏感詞彙。4.1,攔截器是基於java反射機制來實現的,而過濾器是基於函式回撥來實現的。(有人說,攔截器是基於動態代理來實現的)4.2,攔截器不依賴servlet容器,過濾器依賴於servlet容器。4.3,攔截器只對Action起作用,過濾器可以對所有請求起作用。4.4,攔截器可以訪問Action上下文和值棧中的物件,過濾器不能。4.5,在Action的生命週期中,攔截器可以多次呼叫,而過濾器只能在容器初始化時呼叫一次。5,Spring攔截器5.1,抽象類HandlerInterceptorAdapter 我們如果在專案中使用了Spring框架,那麼,我們可以直接繼承HandlerInterceptorAdapter.java這個抽象類,來實現我們自己的攔截器。

    Spring框架,對java的攔截器概念進行了包裝,這一點和Struts2很類似。HandlerInterceptorAdapter繼承了抽象介面HandlerInterceptor。

    [java] view plain copy print?package org.springframework.web.servlet.handler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public abstract class HandlerInterceptorAdapter implements HandlerInterceptor{ // 在業務處理器處理請求之前被呼叫 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{ return true; } // 在業務處理器處理請求完成之後,生成檢視之前執行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception{ } // 在DispatcherServlet完全處理完請求之後被呼叫,可用於清理資源 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception{ } }

    接下來我們看一下Spring框架實現的一個簡單的攔截器UserRoleAuthorizationInterceptor,UserRoleAuthorizationInterceptor繼承了抽象類HandlerInterceptorAdapter,實現了使用者登入認證的攔截功能,如果當前使用者沒有透過認證,會報403錯誤。

    [java] view plain copy print?package org.springframework.web.servlet.handler; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UserRoleAuthorizationInterceptor extends HandlerInterceptorAdapter{ // 字串陣列,用來存放使用者角色資訊 private String[] authorizedRoles; public final void setAuthorizedRoles(String[] authorizedRoles){ this.authorizedRoles = authorizedRoles; } public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException{ if (this.authorizedRoles != null) { for (int i = 0; i < this.authorizedRoles.length; ++i) { if (request.isUserInRole(this.authorizedRoles[i])) { return true; } } } handleNotAuthorized(request, response, handler); return false; } protected void handleNotAuthorized(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException{ // 403表示資源不可用。伺服器理解使用者的請求,但是拒絕處理它,通常是由於許可權的問題 response.sendError(403); } }

    下面,我們利用Spring框架提供的HandlerInterceptorAdapter抽過類,來實現一個自定義的攔截器。我們這個攔截器叫做UserLoginInterceptorBySpring,進行登入攔截控制。工作流程是這樣的:如果當前使用者沒有登入,則跳轉到登入頁面;登入成功後,跳轉到之前訪問的URL頁面。

    [java] view plain copy print?import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; /** * @description 利用spring框架提供的HandlerInterceptorAdapter,實現自定義攔截器 */ public class UserLoginInterceptorBySpring extends HandlerInterceptorAdapter{ // 在業務處理器處理請求之前被呼叫 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{ // equalsIgnoreCase 與 equals的區別? if("GET".equalsIgnoreCase(request.getMethod())){ //RequestUtil.saveRequest(); } System.out.println("preHandle..."); String requestUri = request.getRequestURI(); String contextPath = request.getContextPath(); String url = requestUri.substring(contextPath.length()); System.out.println("requestUri" + requestUri); System.out.println("contextPath" + contextPath); System.out.println("url" + url); String username = (String) request.getSession().getAttribute("username"); if(null == username){ // 跳轉到登入頁面 request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); return false; } else{ return true; } } // 在業務處理器處理請求完成之後,生成檢視之前執行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception{ System.out.println("postHandle..."); if(modelAndView != null){ Map<String, String> map = new HashMap<String, String>(); modelAndView.addAllObjects(map); } } // 在DispatcherServlet完全處理完請求之後被呼叫,可用於清理資源 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception{ System.out.println("afterCompletion..."); } }

    攔截器是依賴Java反射機制來實現的。攔截器的實現,用到的是JDK實現的動態代理,我們都知道,JDK實現的動態代理,需要依賴介面。攔截器是在面向切面程式設計中應用的,就是在你的service或者一個方法前呼叫一個方法,或者在方法後呼叫一個方法。攔截器不是在web.xml,比如struts在struts.xml中配置。

    [java] view plain copy print?public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("方法呼叫前,可以執行一段程式碼" + method.getName()); result = method.invoke(this.targetObj, args); System.out.println("方法呼叫後,可以執行一段程式碼 " + method.getName()); return result; }

    總結: 1.過濾器(Filter):所謂過濾器顧名思義是用來過濾的,Java的過濾器能夠為我們提供系統級別的過濾,也就是說,能過濾所有的web請求,這一點,是攔截器無法做到的。在Java Web中,你傳入的request,response提前過濾掉一些資訊,或者提前設定一些引數,然後再傳入servlet或者struts的action進行業務邏輯,比如過濾掉非法url(不是login.do的地址請求,如果使用者沒有登陸都過濾掉),或者在傳入servlet或者struts的action前統一設定字符集,或者去除掉一些非法字元(聊天室經常用到的,一些罵人的話)。filter 流程是線性的,url傳來之後,檢查之後,可保持原來的流程繼續向下執行,被下一個filter, servlet接收。 2.監聽器(Listener):Java的監聽器,也是系統級別的監聽。監聽器隨web應用的啟動而啟動。Java的監聽器在c/s模式裡面經常用到,它會對特定的事件產生產生一個處理。監聽在很多模式下用到,比如說觀察者模式,就是一個使用監聽器來實現的,在比如統計網站的線上人數。又比如struts2可以用監聽來啟動。Servlet監聽器用於監聽一些重要事件的發生,監聽器物件可以在事情發生前、發生後可以做一些必要的處理。 3.攔截器(Interceptor):java裡的攔截器提供的是非系統級別的攔截,也就是說,就覆蓋面來說,攔截器不如過濾器強大,但是更有針對性。Java中的攔截器是基於Java反射機制實現的,更準確的劃分,應該是基於JDK實現的動態代理。它依賴於具體的介面,在執行期間動態生成位元組碼。攔截器是動態攔截Action呼叫的物件,它提供了一種機制可以使開發者在一個Action執行的前後執行一段程式碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分程式碼的方式。在AOP中,攔截器用於在某個方法或者欄位被訪問之前,進行攔截然後再之前或者之後加入某些操作。java的攔截器主要是用在外掛上,擴充套件件上比如 Hibernate Spring Struts2等,有點類似面向切片的技術,在用之前先要在配置檔案即xml,檔案裡宣告一段的那個東西。

    ----------------河南新華

  • 中秋節和大豐收的關聯?
  • 漿白釉漁樵故事紋青花棒槌瓶,請藏友們鑑評?怎麼樣?