1. 程式人生 > >SSH2——filter過濾器

SSH2——filter過濾器

-- 回調函數 destroy 客戶 tin 這一 釋放 one containe


概述:

過濾器是Servlet2.3以上新添加的一個功能,其技術也是很強大的。通過Filter技術能夠對WEBserver的文件進行攔截,從而實現一些特殊的功能。

在JSP開發應用中也是必備的技能之中的一個。

Filter能夠改變一個request(請求)和改動一個response(響應)。Filter不是一個Servlet,它不能產生一個response,它能夠在一個requsst到達Servlet之前預處理request,也能夠在離開Servlet時處理response。


原理:

當Web容器接受到一個對資源的請求時。它將推斷是否有過濾器與這個資源關聯。假設有的話容器把請求交給過濾器處理,在過濾器中,能夠改變請求的內容,或者又一次設置請求的信息,然後再將請求發送給目標資源,當目標資源對請求做出響應後,容器相同將響應先轉發給過濾器,過濾器能夠對響應的內容進行轉換,然後再將響應發送到client

技術分享

在一個Web應用中,是能夠部署多個過濾器的。組成一個過濾器鏈。過濾器鏈中的每一個過濾器負責特定的操作和任務,client的請求在這些過濾器之間傳遞,直到目標資源。WEBserver依據Filter在web.xml文件裏的註冊順序決定先調用哪一個Filter,當地一個Filter的doFilter方法被調用時,WEBserver會創建一個Filter鏈的FilterChain對象傳遞給該方法。

技術分享


說明:FIlter不是一個標準的Servlet,不能處理用戶請求,也不能對client生成響應。

主要用於對HttpServletRequest進行預處理,也能夠對HttpServletResponse進行後處理。


HttpServletRequest和HttpServletResponse工作流程

首先,在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest,然後依據須要檢查HttpServletRequest,也能夠改動HttpServletRequest頭和數據,當HttpServletResponse到達client之前。攔截HttpServletResponse,依據須要檢查HttpServletResponse。也能夠改動HttpServletResponse的頭和數據。

比方說當對用戶發送的數據進行過濾,替換時就使用到這一點。


Filter使用基礎

1.一個Filter必須實現javax.servlet,Filter接口並定義下面三個方法:

<!--Filter實例化後進行初始化的回調方法-->

public void init(FilterConfig config)

<!--處理過濾器的方法-->

public void doFilter(ServletRequest request,ServletResponse response,FilterChain)

<!--在釋放時回調的方法-->

public void destory()


2.FilterConfig接口


在配置filter時,能夠使用<init-parm>為filter配置一些初始化參數,當web容器實例化Filter對象時。調用init方法時,會把封裝了filter初始化參數的filterConfig對象傳遞進來,因此在編寫filter時,通過filterConfig對象的方法,就能夠通過getFilterName()獲得filter的名字,使用String getInitParamerter(String name)獲得在部署描寫敘述中指定名稱的初始化參數的值等


3.在web.xml文件裏使用<filter>和<filter-mapping>元素對編寫的filter類進行註冊。並設置它所能攔截的資源。

以下通過介紹登陸的時加上過濾器這個樣例介紹web.xml怎麽配置

Web.xml

<filter>
    <filter-name>SessionFilter</filter-name>
    <filter-class>com.action.login.SessionFilter</filter-class>
    <init-param>
        <param-name>logonStrings</param-name><!-- 對登錄頁面不進行過濾 -->
        <param-value>/project/index.jsp;login.do</param-value>
    </init-param>
    <init-param>
        <param-name>includeStrings</param-name><!-- 僅僅對指定過濾參數後綴進行過濾 -->
        <param-value>.do;.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>redirectPath</param-name><!-- 未通過跳轉到登錄界面 -->
        <param-value>/index.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>disabletestfilter</param-name><!-- Y:過濾無效 -->
        <param-value>N</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>SessionFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


FilterServlet

package com.action.login;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;


  <!-- 推斷用戶是否登錄,未登錄則退出系統返回登陸頁-->
public class SessionFilter implements Filter {
    
    public FilterConfig config;
    
    public void destroy() {
        this.config = null;
    }
    
    public static boolean isContains(String container, String[] regx) {
        boolean result = false;

        for (int i = 0; i < regx.length; i++) {
            if (container.indexOf(regx[i]) != -1) {
                return true;
            }
        }
        return result;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hrequest = (HttpServletRequest)request;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
        
        String logonStrings = config.getInitParameter("logonStrings");        <!--登錄登陸頁面-->
        String includeStrings = config.getInitParameter("includeStrings");    <!--過濾資源後綴參數-->
        String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");<!--沒有登陸轉向頁面-->
        String disabletestfilter = config.getInitParameter("disabletestfilter");<!-- 過濾器是否有效-->
        
        if (disabletestfilter.toUpperCase().equals("Y")) {    <!--過濾無效-->
            chain.doFilter(request, response);
            return;
        }
        String[] logonList = logonStrings.split(";");
        String[] includeList = includeStrings.split(";");
        
        if (!this.isContains(hrequest.getRequestURI(), includeList)) {<!--僅僅對指定過濾參數後綴進行過濾-->
            chain.doFilter(request, response);
            return;
        }
        
        if (this.isContains(hrequest.getRequestURI(), logonList)) {<!--對登錄頁面不進行過濾-->
            chain.doFilter(request, response);
            return;
        }
        
        String user = ( String ) hrequest.getSession().getAttribute("useronly");<!--推斷用戶是否登錄-->
        if (user == null) {
            wrapper.sendRedirect(redirectPath);
            return;
        }else {
            chain.doFilter(request, response);
            return;
        }
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;
    }
}

這樣FIlter就能夠幫你過濾了。
總結:上篇文章簡單對攔截器有一個了解,今天 又學習了FIlter這個過濾器。除了用法不一樣以外它們還有非常多不同的地方,如:filter基於回調函數。我們須要實現的filter接口中doFilter方法就是回調函數。而interceptor則基於java本身的反射機制,這是兩者最本質的差別,filter是依賴於servlet容器的。即僅僅能在servlet容器中運行,非常顯然沒有servlet容器就無法來回調doFilter方法。而interceptor與servlet容器無關。還有就是攔截器由spring管理,僅僅對action起作用,不能攔截jsp頁面、圖片等其它資源。

攔截器截獲用戶對action的訪問,如須要跳轉,僅僅需如action一樣返回一個result,spring依據result的配置運行跳轉。如無需跳轉。可調用invocation.invoke();方法來運行用戶請求的action。攔截器在action之前開始,在action完畢後結束。肯定還有非常多不同的地方,學習到這裏僅僅體會到了這些。歡迎大家一起分享。





SSH2——filter過濾器