Servlet過濾器
來源:程序員人生 發布時間:2014-09-07 10:10:30 閱讀次數:3325次
過濾器是Web程序中的可重用組件,它在Servlet2.3規范中被引入,其應用十分廣泛,為java Web程序的開始帶來了更強大的功能。
Servlet過濾器是客戶端與目標資源間的中間層組件,用于攔截客戶的請求與相應信息,當WEB容器接收到一個用戶的請求,Web容器判斷此請求是否與過濾器對象相關聯,如果相關聯,容器將這一請求交給過濾器進行處理,在處理過程中過濾器可以對請求進行操作,如更改請求中的信息數據,在過濾器處理完成后,在將這一請求交個其他業務處理,當所有業務處理完成,需要對客戶端進行相應時,容器又將相應交個過濾器進行很粗魯,過濾器處理響應完成將響應發送到客戶端。
在多個處理器的處理方式中,容器首先將請求交給第一個過濾器處理,處理完成后交給下一個過濾器處理,以此類推,直至最后一個過濾器處理完成,當需要對客戶端回應時,將按照相反的方向對回應進行處理,直到交個第一個過濾器,最后發送給客戶端回應。
過濾器API
過濾器與Servlet非常相似,他通過三個核心接口進行操作,分別是Filter接口、FilterChain接口與FilterConfig接口。
Filter接口
Filter接口位于javax.servlet包中,與Servlet接口非常類似、定義一個過濾器對象需要實現此接口,子啊Filter接口中包含三個方法:
方法
|
說明
|
public void init(FilterConfig filterConfig)
|
過濾器的初始化方法,容器調用此方法完成過濾器的初始化,對于每一個Filter實例,此方法只被調用一次。
|
public void doFilter(ServletRequest request,ServlertResponse response,FilterChain chain)
|
此方法與Servlet的service()方法類似,當請求以及響應交給過濾器時,過濾器調用此方法進行過濾處理。
|
public void destroy()
|
在過濾器生命周期結束時調用此方法,此方法可用于釋放過濾器所占用的所有資源。
|
FilterChain接口
FilterChain接口位于javax.servlet包中,此接口由容器實現,在FilterChain接口只包含一個方法,其聲明如下:
void doFilter(ServletRequest request,ServletResponse response)throws IOException,ServletException
此方法用于將過濾器處理的請求或響應傳遞給下一個過濾器對象。在多個顧慮器的Web應用中,可以通過此方法進行傳遞。
FilterConfig接口。
FilterConfig接口位于javax.servlet包中,此接口由容器進行實現,用于獲取過濾器初始化期間的參數信息,其方法及說明如下:
方法
|
說明
|
public String getFilterName()
|
返回過濾器名稱
|
public String getInitParameter(String name)
|
返回初始化名稱為name的參數值
|
public Enumeration getInitParameterNames()
|
返回所有初始化參數名的枚舉集合。
|
public ServletContext getServletContext()
|
返回Servlet的上下文對象。
|
下面看一下如何通過Filter接口創建一個過濾器對象
package Filter;
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;
public class MyFilter implements Filter {
private String encoding=null;
private FilterConfig config = null;
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
配置過濾器
在創建一個過濾器對象后,需要對其進行配置才可以使用,過濾器配置方法與Servlet配置方法類似,都通過web.xml文件進行配置。其配置方法由以下兩步實現:
1、 聲明過濾器對象。
在web.xml文件中通過<filter>標簽聲明一個過濾器對象,在此標簽中包含三個常用的子元素,分別是:<filter-name>、<filter-class>和<init-param>。其中<filter-name>元素用于指定過濾器名稱,此名稱為自定義名稱。<filter-class>元素用于指定過濾器對象的完整位置,包含過濾器對象的包名和類名;<inti-param>元素用于設定過濾器的初始化參數。<init-param>元素包括兩個常用的子元素,分別是<param-name>和<param-value>。其中<param-name>用于指定初始化參數的名稱,<param-value>用于指定初始化參數的值。配置方法如下:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>Filter.MyFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
映射過濾器
在web.xml中聲明了過濾器對象后,需要映射訪問過濾器過濾的對象,此操作為<filter-mapping>標簽進行配置。在<filter-mapping>標簽中主要配置過濾器的名稱,關聯的URL樣式、對應的請求方式等。其配置方法如下:
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-name>用于指定過濾器名稱,此名稱與<filter>標簽中的<filter-name>相對應
<url-pattern>用于指定過濾器關聯的URL樣式,設置為/*為關聯全部的url
<dispatcher>用于指定過濾器對應的請求方式
dispatcher可選值及說明如下:
可選值
|
說明
|
REQUEST
|
當客戶端直接請求時,則通過過濾器進行處理
|
INCLUDE
|
當客戶端通過RequestDispatcher對象的include()方法請求處理時,通過過濾器進行處理
|
FORWARD
|
當客戶端通過RequestDispatcher對象的forward()方法請求時,通過過濾器進行處理
|
ERROR
|
當聲明式異常產生時,則通過過濾器處理
|
下面看一個編寫字符編碼過濾器的具體示例:
首先創建一個字符編碼過濾器類MyFilter,此類實現Filter接口,以及重寫他的三個方法。代碼如下:
package Filter;
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;
public class MyFilter implements Filter {
private String encoding=null;
private FilterConfig config = null;
@Override
public void init(FilterConfig config) throws ServletException {
this.config=config;
this.encoding = config.getInitParameter("encoding");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if(encoding !=null){
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
encoding=null;
config=null;
}
}
MyFilter類的init()方法,用于讀取過濾器的初始化參數,參數encoding為實例中所用到的字符編碼。在doFilter()方法中,分別將request和response對象中的編碼格式設置為讀取到的編碼格式,最后在destory()方法中將其屬性設置為null,將被垃圾回收器回收。
在web.xml文件中對過濾器進行配置。關鍵代碼如下:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>Filter.MyFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
在web.xml配置文件中需要對過濾器進行聲明及驗證。其中聲明過程通過<init-param>指定了初始化參數的字符集編碼為utf-8。
通過請求對過濾器進行驗證。實例中使用表單向Servlet發送中文信息進行測試,其中表單信息放在Form.jsp頁面中,代碼如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="servlet/MyServlet" method = "get">
<table>
<tr>
<td>用戶名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密碼:</td>
<td><input type="password" name = "password"></td>
</tr>
</table>
<input type="submit" value="提交"/>
</form>
</body>
</html>
這一請求將有Servlet對象MyServlet類進行處理,此類使用doGet()方法接受表單的請求并將表單中的username和password進行驗證后,在頁面輸出相應的信息。其代碼如下:
package Servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
//response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
String password = request.getParameter("password");
if(username.equals(password)){
out.print(username+"歡迎你!");
}else{
out.print("您輸入密碼有誤,請重新輸入!");
}
out.flush();
out.close();
}
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈