Servlet過慮器
過濾器是在請求的預處理和後處理時調用的對象。
主要用於執行轉換,日誌記錄,壓縮,加解密,輸入驗證等過濾任務。
servlet過濾器是可插拔的,即它在web.xml
文件中定義,如果從web.xml
文件中刪除過濾項,則過濾器將被自動刪除,因此不需要手動更改Servlet
。所以過濾器維護成本會比較低。
參考模型圖 -
注意:與Servlet不同,一個過濾器不依賴於另一個過濾器。
過濾器的使用
- 記錄所有傳入的請求
- 記錄來自標計算機的IP地址的請求
- 轉變/轉換
- 數據壓縮
- 加密和解密
- 輸入驗證等
過濾器的優點
- 過濾器是可插拔的。
- 一個過濾器不依賴於另一個資源。
- 維護少,比較容易維護。
過濾器API
像Servlet一樣,過濾器也有自己的API。 javax.servlet
包中包含Filter API的三個接口,它們分別如下所示 -
-
Filter
-
FilterChain
-
FilterConfig
Filter接口
要創建一個過濾器,必須要實現Filter
接口。Filter
接口爲過濾器提供了生命週期方法。
方法
描述
public void init(FilterConfig config)
init()
方法只被調用一次,用於初始化過濾器。
public void doFilter(HttpServletRequest request,HttpServletResponse response, FilterChain chain)
當用戶請求過濾器所映射到資源時,會調用doFilter()
方法,它用於執行過濾任務。
public void destroy()
當過濾器從服務中取出時,調用此方法(僅一次)。
FilterChain接口
FilterChain
對象負責調用鏈中的下一個過濾器或資源。對象在Filter
接口的doFilter
方法中傳遞。FilterChain
接口只包含一個方法:
-
public void doFilter(HttpServletRequest request,HttpServletResponse response)
:它將控件傳遞給下一個過濾器或資源。
如何定義過濾器
我們可以使用與servlet
相同方式來定義過濾器。下面來看看過濾器和過濾器映射的元素。在web.xml文件配置如下 -
<web-app>
<filter>
<filter-name>...</filter-name>
<filter-class>...</filter-class>
</filter>
<filter-mapping>
<filter-name>...</filter-name>
<url-pattern>...</url-pattern>
</filter-mapping>
</web-app>
對於映射過濾器,可以使用url-pattern
或servlet-name
。 url-pattern
元素比servlet-name
元素具有優勢,即它可以應用於servlet
,JSP
或HTML
資源。
過濾器的簡單示例
在這個例子中,只是顯示在請求的後處理後自動調用過濾器的信息。
打開Eclipse,創建一個動態Web項目:SimpleFilter,其完整的目錄結構如下所示 -
以下是這個項目中的幾個主要的代碼文件。
文件:index.html -
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>過濾器的簡單示例</title>
</head>
<body>
<div style="font-align: center;">
<a href="servlet1">查看過濾器調用信息</a>
</div>
</body>
</html>
文件:MyFilter.java
package com.yiibai;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
public class MyFilter implements Filter {
public void init(FilterConfig arg0) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("過濾器調用之前<br/>");
chain.doFilter(request, response);// sends request to next resource
out.print("過濾器調用之後<br/>");
}
public void destroy() {
}
}
文件:MyServlet.java
package com.yiibai;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print(" -- 這是一個簡單的測試Servlet.<br>");
}
}
文件:web.xml -
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>SimpleFilter</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>s1</servlet-name>
<servlet-class>com.yiibai.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>s1</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
<filter>
<filter-name>f1</filter-name>
<filter-class>com.yiibai.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>f1</filter-name>
<url-pattern>/servlet1</url-pattern>
</filter-mapping>
</web-app>
在編寫上面代碼後,部署此Web應用程序(在項目名稱上點擊右鍵->」Run On Server…」),打開瀏覽器訪問URL: http://localhost:8080/SimpleFilter/ ,如果沒有錯誤,應該會看到以下結果 -
點擊鏈接,得到 以下結果 -
在上圖中,可以看到過濾器調用的順序。