filter servelet 相關

轉載於http://www.javanb.com/jsp/1/3873.html

java.servlet.Filter的應用
        關鍵字: Filter的應用
        Filter 技術是servlet 2.3 新增加的功能.servlet2.3是sun公司與2000年10月發佈的,它的開發者包括許多個人和公司團體,充分體現了sun公司所倡導的代碼開放性原則.由於衆多的參與者的共同努力,servlet2.3比以往功能都強大了許多,而且性能也有了大幅提高.
        它新增加的功能包括:
        1. 應用程序生命週期事件控制;
        2. 新的國際化;
        3. 澄清了類的裝載規則;
        4. 新的錯誤及安全屬性;
        5. 不贊成使用HttpUtils 類;
        6. 各種有用的方法;
        7. 闡明並擴展了幾個servlet DTD;
        8. filter功能. 54com.cn
        其中最重要的就是filter功能.它使用戶可以改變一個request和修改一個response. Filter 不是一個servlet,它不能產生一個response,它能夠在一個request到達servlet之前預處理request,也可以在離開servlet時處理response.換種說法,filter其實是一個”servlet chaining”(servlet 鏈).一個filter 包括:
        1. 在servlet被調用之前截獲;
        2. 在servlet被調用之前檢查servlet request;
        3. 根據需要修改request頭和request數據;
        4. 根據需要修改response頭和response數據;
        5. 在servlet被調用之後截獲.
        你能夠配置一個filter 到一個或多個servlet;單個servlet或servlet組能夠被多個filter 使用.幾個實用的filter 包括:用戶辨認filter,日誌filter,審覈filter,加密filter,符號filter,能改變xml內容的XSLT filter等.
        一個filter必須實現javax.servlet.Filter接口並定義三個方法:
54com.cn


        1.void setFilterConfig(FilterConfig config) //設置filter 的配置對象;
        2. FilterConfig getFilterConfig() //返回filter的配置對象;
        3. void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) //執行filter 的工作.
        服務器每次只調用setFilterConfig方法一次準備filter 的處理;調用doFilter方法多次以處理不同的請求.FilterConfig接口有方法可以找到filter名字及初始化參數信息.服務器可以設置FilterConfig爲空來指明filter已經終結.
        每一個filter從doFilter()方法中得到當前的request及response.在這個方法裏,可以進行任何的針對request及response的操作.(包括收集數據,包裝數據等).filter調用chain.doFilter()方法把控制權交給下一個filter.一個filter在doFilter()方法中結束.如果一個filter想停止request處理而獲得對response的完全的控制,那它可以不調用下一個filter.
        一個filter可以包裝request 或response以改變幾個方法和提供用戶定製的屬性.Api2.3提供了HttpServletRequestWrapper 和HttpServletResponseWrapper來實現.它們能分派最初的request和response.如果要改變一個方法的特性,必須繼承wapper和重寫方法.下面是一段簡單的日誌filter用來記錄所有request的持續時間. 54ne.com
 public class LogFilter implements Filter {
FilterConfig config;

public void setFilterConfig(FilterConfig config) {
this.config = config;
}

public FilterConfig getFilterConfig() {
return config;
}

public void doFilter(ServletRequest req,
ServletResponse res,
FilterChain chain) {
ServletContext context = getFilterConfig().getServletContext();
long bef = system.currentTimeMillis();
chain.doFilter(req, res); // no chain parameter needed here
long aft = system.currentTimeMillis();
context.log("Request to " + req.getRequestURI()
+ ": " + (aft-bef));
}
}
 

          當server調用setFilterConfig(),filter保存config信息.在doFilter()方法中通過config信息得到servletContext.如果要運行這個filter,必須去配置到web.xml中.以tomcat4.01爲例:
網管聯盟www.bitsCN.com


    log //filter 名字

    LogFilter //filter class(上例的servlet)
 
    log
    servletname

    servletname
    servletclass

    servletname
    *

    把這個web.xml放到web-inf中(詳請參考tomcat幫助文檔).
    當每次請求一個request時(如index.jsp),先到LogFilter中去並調用doFilter()方法,然後纔到各自的servlet中去.如果是一個簡單的servlet(只是一個頁面,無任何輸出語句),那麼可能的輸出是:
    Request to /index.jsp: 10
 
    Servlet和Filter的url匹配以及url-pattern詳解
    一,servlet容器對url的匹配過程:
    當一個請求發送到servlet容器的時候,容器先會將請求的url減去當前應用上下文的路徑作爲servlet的映射url,比如我訪問的是http://localhost/test/aaa.html,我的應用上下文是test,容器會將http://localhost/test去掉,剩下的/aaa.html部分拿來做servlet的映射匹配。這個映射匹配過程是有順序的,而且當有一個servlet匹配成功以後,就不會去理會剩下的servlet了(filter不同,後文會提到)。其匹配規則和順序如下: 中國網管聯盟www、bitsCN、com
    1. 精確路徑匹配。例子:比如servletA 的url-pattern爲 /test,servletB的url-pattern爲 /* ,這個時候,如果我訪問的url爲http://localhost/test ,這個時候容器就會先 進行精確路徑匹配,發現/test正好被servletA精確匹配,那麼就去調用servletA,也不會去理會其他的servlet了。
    2. 最長路徑匹配。例子:servletA的url-pattern爲/test/*,而servletB的url-pattern爲/test/a/*,此時訪問http://localhost/test/a時,容器會選擇路徑最長的servlet來匹配,也就是這裏的servletB。
    3. 擴展匹配,如果url最後一段包含擴展,容器將會根據擴展選擇合適的servlet。例子:servletA的url-pattern:*.action
    4. 如果前面三條規則都沒有找到一個servlet,容器會根據url選擇對應的請求資源。如果應用定義了一個default servlet,則容器會將請求丟給default servlet(什麼是default servlet?後面會講)。
    根據這個規則表,就能很清楚的知道servlet的匹配過程,所以定義servlet的時候也要考慮url-pattern的寫法,以免出錯。
    對於filter,不會像servlet那樣只匹配一個servlet,因爲filter的集合是一個鏈,所以只會有處理的順序不同,而不會出現只選擇一個filter。Filter的處理順序和filter-mapping在web.xml中定義的順序相同。 網管網bitsCN_com
    二,url-pattern詳解
    在web.xml文件中,以下語法用於定義映射:
    l 以”/’開頭和以”/*”結尾的是用來做路徑映射的。
    l 以前綴”*.”開頭的是用來做擴展映射的。
    l “/” 是用來定義default servlet映射的。
    l 剩下的都是用來定義詳細映射的。比如: /aa/bb/cc.action
    所以,爲什麼定義”/*.action”這樣一個看起來很正常的匹配會錯?因爲這個匹配即屬於路徑映射,也屬於擴展映射,導致容器無法判斷。
    Filter過濾器的使用
    本篇文章是介紹javax.servlet包中Filter的幾個功能,一是字符編碼過濾,二是攔截指文件夾中的文件,實現登錄驗證.實現以上兩個功能需以下幾個步驟:
    1、實現javax.servlet.Filter接口,編寫兩個類,如下:

 /**
* 作用:過濾編碼
*/ 網管聯盟www.bitsCN.com
package filter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
public class EncodingFilter implements Filter
{
protected FilterConfig filterConfig;
private String targetEncoding;
public EncodingFilter()
{
targetEncoding = "gb2312";//直接初始化0912
}
public void init(FilterConfig filterconfig) throws ServletException
{
filterConfig = filterconfig;
//targetEncoding = filterconfig.getInitParameter("encoding");//web.xml掛參初始化
}
public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)
throws IOException, ServletException
{
HttpServletRequest httpservletrequest = (HttpServletRequest)servletrequest;
httpservletrequest.setCharacterEncoding(targetEncoding);
system.out.println("使用" targetEncoding "對請求進行編碼過濾");
filterchain.doFilter(servletrequest, servletresponse);
}
public void setFilterConfig(FilterConfig filterconfig) 54com.cn
{
filterConfig = filterconfig;
}
public void destroy()
{
filterConfig = null;
}
}
/**
* 作用:過濾外界非法的進入頁面
* 注意:使用該功能時,一定要把登錄頁與被過濾文件夾設爲同級,否則會出現循環
*/
package filter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class ManageFilter implements Filter
{
String LOGIN_PAGE;
protected FilterConfig filterConfig;
public ManageFilter()
{
LOGIN_PAGE = "/login.jsp";
}
public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)
throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest) servletrequest;
HttpServletResponse response = (HttpServletResponse) servletresponse;
HttpSession session = request.getSession();
String key = "";
try
{
//通過驗證時在session中存的一個標誌
key = (String) session.getAttribute("key");


中國網管聯盟www_bitscn_com


if (key!= null&&key.equals("ok"))
{

filterchain.doFilter(servletrequest, servletresponse);
}
else
{
response.sendRedirect(LOGIN_PAGE);
system.out.println("被攔截一個未認證的請求");
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
public void setFilterConfig(FilterConfig filterconfig)
{
filterConfig = filterconfig;
}
public void destroy()
{
filterConfig = null;
}
public void init(FilterConfig filterconfig)
throws ServletException
{
filterConfig = filterconfig;
}
}
 

2、在web.xml中做一些設置

code
filter.EncodingFilter

 

manage
filter.ManageFilter


code
/*

 

manage
<!-- <url-pattern>/ShuiBaoRHPWK_NEW/system/ruhepaiwukou/*</url-pattern>-->
/servlets-examples/*
【轉自www.bitsCN.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章