Servlet過濾器的使用
Servlet 過濾器可以動態地攔截請求和響應,以變換或使用包含在請求或響應中的信息。
舉個簡單的例子,比如我們有個網站是需要登錄的,所以在用戶進入每個頁面我們都需要去檢測用戶是否有登錄,這時候我們就需要用到過濾器了。用戶進入需要驗證的頁面都攔截下來,先進入過濾器做判斷,如果有這個用戶的登錄信息,那麼就放行,如果沒有查詢到此用戶的登錄信息,那麼就跳轉到登錄頁面或者其他你想設定的頁面。
(程序的運行需要大量的配置及嚴苛的語法,如果你是第一次學習此內容,按照教程的指導,完全模仿操作。切勿一來就擅自改動,給自己的學習製造障礙!)
下面通過實例理解過濾器的原理和使用。
一、創建項目
IDEA創建web項目,可以參考我另一篇博文:手摸手教你在IDEA創建Web項目及配置Tomcat
二、編寫程序
1. 目錄結構如下
2. 編寫過濾器程序
過濾器必須實現javax.servlet.Filter接口,該接口包含3個方法:init、doFilter、destroy。
- init(FilterConfig filterConfig):Java EE容器創建過濾器實例後調用該方法,用於爲過濾器做準備工作,可以從filterConfig對象讀取配置文件web.xml中爲該過濾器設置的初始化參數。
- doFilter(ServletRequest request, ServletResponse response, FilterChain chain):過濾操作在該方法裏實現,包括檢查、修改請求對象,檢查修改應答對象。參數request是請求對象,response是應答對象,chain用於訪問後續過濾器。
- destroy():Java EE容器在銷燬過濾器實例前調用該方法,用於釋放資源。
實現一個禁止某個地址訪問hello.jsp的例子,首先編寫過濾器程序,然後再配置文件web.xml中進行配置,最後運行。
該程序實現了Filter接口,再init()方法中讀取配置文件的過濾器的參數(禁止訪問的IP地址)。在doFilter()方法中檢查客戶端的IP地址,如果與禁止的地址相同就返回禁止訪問的提示,不調用要訪問的Web資源,在destroy()方法中釋放資源。
AddressFilter.java
package filter;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
public class AddressFilter implements Filter {
private FilterConfig filterConfig = null;
private String addressProhibited = null;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
addressProhibited = filterConfig.getInitParameter("addressProhibited");
//讀取配置文件中的參數
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException,ServletException{
String ip = request.getRemoteAddr();
// 判斷如果是本地localhost的話,就改成127.0.0.1
String address = ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
// 獲取客戶端IP地址
if(address.equals(addressProhibited)) {
// if(true) {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("<html>");
out.print("<head>");
out.print("<title>這個地址禁止訪問</title>");
out.print("</head>");
out.print("<body>");
out.print("<h1 align='center'>這個地址禁止訪問</h1>");
out.print("</body>");
out.print("</html>");
out.flush();
return ;
}
chain.doFilter(request, response);
}
public void destroy() {
this.filterConfig = null;
}
}
2. 編寫web.xml文件
在Tomcat應用服務器的web.xml文件中配置過濾器AddressFilter。
過濾器要在配置文件web.xml中進行配置纔會起作用。配置分爲兩部分,一部分是對過濾器的定義,一部分是過濾器的映射。
先看定義過濾器的部分:
其中<filter-name>定義過濾器的名字,<filter-class>指定過濾器的類,<init-param>和</init-param>之間是該過濾器的參數(就是前面過濾器程序中讀的),其中<param-name>是參數名,<param-value>是參數值。
再看過濾器的映射:
其中是過濾器的名字,< url-pattern>是要經過該過濾器的Web資源,這裏指定的是/hello.jsp,如果是要指定項目都經過該過濾器,可以寫/*。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>AddressFilter</filter-name>
<filter-class>filter.AddressFilter</filter-class>
<init-param>
<param-name>addressProhibited</param-name>
<param-value>127.0.0.1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>AddressFilter</filter-name>
<url-pattern>/hello.jsp</url-pattern>
</filter-mapping>
</web-app>
3. 創建hello.jsp文件
新建一個hello.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>hello</title>
</head>
<body>
正常訪問到hello.jsp
</body>
</html>
4. 測試程序
運行服務器,從calhost:8080/或者127.0.0.1:8080/訪問hello.jsp時,就會出現禁止訪問的提示;而從其他機器訪問時,就能正常訪問。
本機測試:
其他設備測試:
三、問題及解決
import javax.servlet.*; //爆紅
IDEA報錯:java: 程序包javax.servlet不存在。這個問題是由於沒有導入Tomcat依賴造成的,詳細可以看我另一篇博文:IDEA添加Tomcat依賴