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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM