Tomcat與JavaWeb開發技術詳解過濾器

過濾器簡介

過濾器是在Java Servlet2.3中規範定義的,它能夠對Servlet容器傳給Web組件的ServletRequest對象和ServletReponse對象進行檢查和修改。過濾器本身並不生成ServletRequest對象和ServletResponse對象,它只爲Web組件提供如下過濾功能:

  • 過濾器能夠在Web組件被調用之前檢查ServletRequest對象,修改響應頭和相應正文的內容,或者對請求進行預處理操作。

  • 過濾器能夠在Web組件被調用之後檢查ServletResponse對象,修改響應頭和響應正文。

  • 過濾器負責過濾的組件可以是Servlet,JSP或HTML文件。
    在這裏插入圖片描述
    過濾器具有以下特點:

  • 可以檢查ServletRequest和ServletResponse對象,並且可以利用ServletRequestWrapper和ServletReponseWrapper包裝類來修改ServletRequest和ServletResponse對象。

  • 可以在web.xml文件中爲過濾器映射特定的URL。當客戶請求訪問此URL時,Servlet容器會先出發過濾器工作。

  • 多個過濾器可以被串聯在一起,協同爲Web組件過濾請求對象和響應對象。

創建過濾器

所有自定義的過濾器類都必須實現javax.servlet.Filter接口。這個接口包含以下三個過濾器必須實現的方法。

  • init(FilterConfig config):這是過濾器的初始化方法。Web應用啓動時,會先創建包含過濾器配置信息的FileConfig對象,然後創建Filter對象,然後通過該方法的config對象讀取web.xml文件中爲過濾器配置的初始化參數。
public void init(FilterConfig config) throws ServletException {
System.out.println("NoteFilter :init()");

this.config=config;//把Servlet容器提供的FilterConfig對象傳給config成員變量
//讀取ipblock初始化參數
ipblock=config.getInitParameter("ipblock");
//讀取blacklist初始化參數
blackList=config.getInitParameter("blackList");
}
  • doFilter(ServletRequest request, ServletResponse response,FilterChain chain):這個方法完成實際的過濾操作。當用戶請求訪問的URL與過濾器映射的URL匹配時,Servlet容器會先調用過濾器的doFilter方法,chain參數用於訪問後續過濾器或者Web組件。
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("NoteFilter:doFilter");
//判斷客戶IP是否在預定義的拒絕IP地址範圍內,
//如果滿足這一條件,就直接返回拒絕信息,不再調用後續的NoteServlet組件
if (!checkRemoteIP(request, response)) {
return ;
}
//判斷username請求參數表示的姓名是否在黑名單中,
//如果滿足這一條件,就直接返回拒絕信息,不再調用後續的NoteServlet組件
if (!checkUsername(request, response)) {
return;
}
//記錄響應客戶請求的時間
long before=System.currentTimeMillis();
config.getServletContext().log("NoreFiter:before call chain.doFilter()");
//把請求轉發給後續的過濾器或者Web組件
chain.doFilter(request, response);
//記錄響應客戶後的時間
config.getServletContext().log("NoreFiter:after call chain.doFilter()");
long after=System.currentTimeMillis();
StringBuffer name=new StringBuffer();
if (request instanceof HttpServletRequest) {
name=((HttpServletRequest) request).getRequestURL();
}
//記錄響應客戶所花的時間
config.getServletContext().log("NoreFiter:"+name+":"+(after-before)+"ms");

}
  • destroy():Servlet容器在銷燬過濾器對象前調用該方法,在這個方法中可以釋放過濾器佔用的資源。
public void destroy() {
System.out.println("NoteFilter:dodestroy");
config=null;

}

Filter的生命週期包含以下幾個階段:初始化階段運行時階段銷燬階段

發佈過濾器

在發佈過濾器時,必須在web,xml文件中加入元素和元素。元素用來定義一個過濾器,如下:

  <filter>
  <filter-name>NoteFilter</filter-name>
  <filter-class>mypack.NoteFilter</filter-class>
  
  <init-param>
  <param-name>ipblock</param-name>
  <param-value>221.45</param-value>
  </init-param>
  
  <init-param>
  <param-name>blacklist</param-name>
  <param-value>搗蛋鬼</param-value>
  </init-param>
  
  </filter>
  <filter-mapping>
  <filter-name>NoteFilter</filter-name>
  <url-pattern>/node</url-pattern>

  </filter-mapping>

<filter-name>子元素用來指定過濾器的名字,<filter-class>用來指定過濾器的類名,<init-param>子元素爲過濾器實例提供初始化參數。 <filter-mapping>用於過濾器映射特定的URL。

串聯過濾器:

多個過濾器可以串聯起來協同工作,Servlet容器將根據它們在web.xml中定義的先後順序,依次調用它們的doFilter()方法。假定有兩個過濾器串聯起來,它們的doFilter()方法均採用如下結構:

code1;

chain.doFilter();

code2;

關於chain.doFilter(request,response)
他的作用是將請求轉發給過濾器鏈上下一個對象。這裏的下一個指的是下一個filter,如果沒有filter那就是你請求的資源。 一般filter都是一個鏈,web.xml 裏面配置了幾個就有幾個。一個一個的連在一起

request -> filter1 -> filter2 ->filter3 -> .... -> request resource.

例如在doFilter()中調用chain.doFilter(request,myWrappedResp);

將名爲myWrappedResp的對象傳給下一個Filter。

包裝設計模式

包裝設計模式具有以下特點:

  • 以對客戶程序透明的方式,動態地給一個對象附加上更多的功能,或者秀愛這個對象的部分功能

  • 假定類A是類B的包裝類,那麼類A和類B具有同樣的接口,並且類A擁有類B的實例,類A借 助類B的實例來實現接口。

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