Servlet之過濾器Filter詳解


一、過濾器的基本工作原理

1、過濾器的基本工作原理 

過濾器的基本工作原理如圖4-8示。


2、過濾器的特點 
過濾器具備有以下特點: 
(1)它是聲明式的 
(2)它是動態的
(3)它是模塊化的 
(4)它是可移植的 
(5)它是可重用的 
(6)它是透明的 


二、過濾器的API接口及部署信息 
1、javax.servlet.Filter接口 
(1)public void init(FilterConfig filterConfig) throws ServletException 
init()方法執行初始化操作
(2) public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws java.io.IOException,ServletException 
過濾器的業務邏輯代碼在doFilter()方法內實現 
(3)public void destroy() 
在銷毀一個過濾器對象之前,此方法被調用來釋放init()中申請的資源,這個方法的執行,表示一個過濾器的生命期結束

2、 javax.servlet.FilterConfig接口
(1)public java.util.Enumeration getInitParameterNames() 
將初始化參數的變量名讀至枚舉型對象中。 
(2)public java.lang.String
                                 getInitParameter(java.lang.String name) 
讀取指定變量名的初始化參數值,如果沒有此參數,則返回Null值。 
(3)public ServletContext getServletContext() 
獲得當前Web應用的ServletContext對象。 

3、javax.servlet. FilterChain接口 
接口中關鍵的方法為:
public void doFilter(ServletRequest  request,
ServletResponse response)  throws  java.io.IOException,ServletException 

4、過濾器的部署 
在WEB-INF\web.xml中部署一個過濾器的過程有:注冊過濾器、映射過濾器
(1)注冊過濾器 
過濾器在Web應用中注冊后才會被容器加載運行。在web.xml中注冊過濾器的方法如下示:

<filter>
      <filter-name>my1</filter-name>
      <filter-class>com.abc.mis.Filter1</filter-class>
      <init-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
      </init-param>
</filter>

容器為一個<filter></filter>元素創建一個過濾器實例,同一個過濾器類可以生成多個實例,此時只需要部署多個<filter></filter>元素,例如:
 <filter>
      <filter-name>my1</filter-name>
      <filter-class>com.abc.mis.Filter1</filter-class>
      <init-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
      </init-param>
</filter>

(2)映射過濾器 
過濾器映射就是定義此過濾器的激活條件,一般是通過目標資源的URI模式和請求的類型來定義。URI中可以使用通配符“*”來表達請求的URI模式。過濾器映射的基本方法如下示: 
<filter-mapping>
      <filter-name>my1</filter-name>
      <url-pattern>/test/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
</filter-mapping>


三、第一個過濾器程序
過濾器的基本編程過程是: 
第一步:編輯與編譯過濾器程序,把編譯后得到的包文件夾及*.class類發布到ROOT\WEB-INF\classes文件夾下。 
第二步:編輯WEB-INF\web.xml文件,添加過濾器的部署信息。 
第三步:重啟Tomcat或重載Web應用,使過濾器生效。 

【例】:定義三個過濾器:
如果用戶訪問“/test”下的資源時,過濾器1被激活,它判斷用戶是否已經登錄,如果沒有登錄則中斷請求,並返回404錯誤信息,如果已經登錄則將請求轉發給下一個過濾器。
定義過濾器2,當請求“/*”資源並且請求是來自客戶端時它才被激活,顯示提示信息,然后把請求轉發給下一個過濾器。
過濾器3的功能同過濾器2,但它的請求類型為REQUEST或FORWARD。

操作步驟如下:
(1) 啟動JC4,新建一個類“Filter1”,在代碼編輯窗口中輸入如下的代碼: 

<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Filter1 implements Filter {

private FilterConfig config = null;

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

public void destroy() {
config = null;
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
response.setCharacterEncoding("GB2312");
PrintWriter out=response.getWriter();
HttpSession session=((HttpServletRequest)request).getSession();

System.out.println("過濾器1工作,請求轉下一個處理..");
out.print("<br>請求到達目標資源前過濾器2添加的信息<br>");

String loginStatus=(String)session.getAttribute("loginName");
if(loginStatus==null)
{
out.print("<br>你沒有登陸,無房訪問資源!<br>");
return;
}
else
chain.doFilter(request, response);

System.out.println("目標資源輸出信息返回到過濾器1...");
out.print("<br>目標資源輸出信息返回時過濾器2添加的信息<br>");


}
}</span></span>

(2)編譯Filter1程序,成功后,Filter1.class文件會被JC4自動存放至c:\tomcat\webapps\ROOT\WEB-INF\classes文件夾下,用“我的電腦”查看並核實。 
(3)啟動JC4,新建一個類“Filter2”,在代碼編輯窗口中輸入如下的代碼:

<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Filter2 implements Filter {

private FilterConfig config = null;

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

public void destroy() {
config = null;
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
response.setCharacterEncoding("GB2312");
PrintWriter out=response.getWriter();

System.out.println("過濾器2工作,請求轉下一個處理..");
out.print("<br>請求到達目標資源前過濾器2添加的信息<br>");

chain.doFilter(request, response);

</span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"> <span style="white-space:pre"></span>System.out.println("目標資源輸出信息返回到過濾器2...");
out.print("<br>目標資源輸出信息返回時過濾器2添加的信息<br>"); </span></span>
}}

 

(4)編譯Filter2程序。 (5)啟動JC4,新建一個類 “Filter3”,在代碼編輯窗口中輸入如下的代碼:

<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Filter3 implements Filter {

private FilterConfig config = null;

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

public void destroy() {
config = null;
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
</span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"><span style="white-space:pre"></span>System.out.println("過濾器3工作,請求轉下一個處理..");
out.print("<br>請求到達目標資源前過濾器3添加的信息<br>");

chain.doFilter(request, response);

</span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"> <span></span>System.out.println("目標資源輸出信息返回到過濾器3...");
out.print("<br>目標資源輸出信息返回時過濾器3添加的信息<br>"); </span></span>

 
}} 
 
(6)編譯Filter3程序。 
(7)部署以上三個過濾器,得到一個過濾器鏈為:過濾器3→過濾器1→過濾器2。
編輯WEB-INF\web.xml文件,添加如下的部署信息:




(8)定義實驗用JSP資源。啟動DW8,完成以下任務: 
新建exam406.jsp,在設計視圖中輸入提示文字“當前是/exam406.jsp 資源”。 
新建exam407.jsp,在代碼視圖中輸入以下代碼: 
<body>
  <%
     session.setAttribute("loginName","tom");
out.print("成功登錄,可以訪問/test下的資源了!");
  %>
</body> 

新建exam408.jsp,在設計視圖中,將站點中的“ROOT\tomcat.gif”圖片插入文檔中。 
在站點根文件夾下新建一個/test下級文件夾。
在/test文件夾下建立一個index.jsp文件,在設計視圖中輸入提示文字“/test的首頁”。 
新建exam409.jsp,在代碼視圖中輸入以下代碼: 

<body>
<%
    RequestDispatcher go=application.getRequestDispatcher("/exam406.jsp");
go.forward(request,response);
%>
</body> 
(9)啟動Tomcat,自行完成測試即可。




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com