JSP Filter(過濾器)簡單例項
什麼是JSP過濾器
過濾器是可用於 Servlet 程式設計的 Java 類,可以實現以下目的:
- 在客戶端的請求訪問後端資源之前,攔截這些請求。
- 在伺服器的響應傳送回客戶端之前,處理這些響應。
根據規範建議的各種型別的過濾器:
- 身份驗證過濾器(Authentication Filters)。
- 資料壓縮過濾器(Data compression Filters)。
- 加密過濾器(Encryption Filters)。
- 觸發資源訪問事件過濾器。
- 影象轉換過濾器(Image Conversion Filters)。
- 日誌記錄和稽核過濾器(Logging and Auditing Filters)。
- MIME-TYPE 鏈過濾器(MIME-TYPE Chain Filters)。
- 標記化過濾器(Tokenizing Filters)。
- XSL/T 過濾器(XSL/T Filters),轉換 XML 內容。
過濾器通過 Web 部署描述符(web.xml)中的 XML 標籤來宣告,然後對映到應用程式的部署描述符中的 Servlet 名稱或 URL 模式。
當 Web 容器啟動 Web 應用程式時,它會為你在部署描述符中宣告的每一個過濾器建立一個例項。
Filter的執行順序與在web.xml配置檔案中的配置順序一致,一般把Filter配置在所有的Servlet之前。
Servlet過濾器方法
過濾器是一個實現了 javax.servlet.Filter 介面的 Java 類。javax.servlet.Filter 介面定義了三個方法:
public void init(FilterConfig filterConfig){
web 應用程式啟動時,web 伺服器將建立Filter 的例項物件,並呼叫其init方法,讀取web.xml配置,完成物件的初始化功能,從而為後續的使用者請求作好攔截的準備工作(filter物件只會建立一次,init方法也只會執行一次)。開發人員通過init方法的引數,可獲得代表當前filter配置資訊的FilterConfig物件(見後文例項)。
}
public void doFilter (ServletRequest, ServletResponse, FilterChain){
該方法完成實際的過濾操作,當客戶端請求方法與過濾器設定匹配的URL時,Servlet容器將先呼叫過濾器的doFilter方法。FilterChain使用者訪問後續過濾器。
}
public void destroy(){
Servlet容器在銷燬過濾器例項前呼叫該方法,在該方法中釋放Servlet過濾器佔用的資源。
}
JSP過濾器例項
本例項將會實現一個攔截對doFilterTest.jsp的訪問請求,並將該請求處理為對百度首頁的訪問。
首先看看,沒有實現過濾器的效果。
無過濾器
index.html裡的程式碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Filter Test</title>
<script src="js/jquery-3.2.1.js"></script>
</head>
<body>
<p>瀏覽器請求訪問doFilterTest.jsp</p>
<form action="doFilterTest.jsp">
<button type="submit">訪問doFilterTest.jsp</button><br>
</form>
</body>
</html>
doFilterTest.jsp裡的程式碼:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>filerTest</title>
</head>
<body>
<p>這是點選filterTest後跳轉的頁面。</p>
<p style="color:red;">接下來,我將在過濾器攔截請求該頁面</p>
</body>
</html>
web.xml(src/main/webapp/WEB-INF目錄下)裡的程式碼:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
效果:
現在實現新增過濾器的效果。
有過濾器
實現過濾瀏覽器(客戶端)對doFilterTest.jsp的請求。
index.html與doFilterTest.jsp的程式碼不變。
在src/main/java裡新增繼承Filter類的TestFilter過濾器類。
TestFilter.java裡的程式碼:
package com.demo;//注意包名,這是我自己建的包。
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
//獲取初始化引數,定義在web.xml裡的<init--param>...</init--param>
System.out.println("web應用程式啟動時,讀取web.xml配置,完成初始化。");
String site_init = config.getInitParameter("site_init");
System.out.println("開發人員通過init方法的引數,可獲得代表當前filter配置資訊的FilterConfig物件:"+site_init);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("處理客戶端訪問後端資源的請求,阻止訪問doFilterTest,轉向訪問百度。");
//過濾器處理該請求,返回百度首頁
((HttpServletResponse)response).sendRedirect("https://www.baidu.com/");
return;
}
@Override
public void destroy() {
}
}
在web.xml配置過濾器:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 定義Filter -->
<filter>
<!-- Filter的名字 -->
<filter-name>TestFilter</filter-name>
<!-- Filter的實現類 -->
<filter-class>com.demo.TestFilter</filter-class>
<init-param>
<param-name>site_init</param-name>
<param-value>https://tigeryoyo.github.io/</param-value>
</init-param>
</filter>
<!-- 定義Filter攔截的URL地址 -->
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/doFilterTest.jsp</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
效果:
啟動tomcat,檢視console控制檯:
可以看到,在tomcat完全啟動成功之前,進入了過濾器的init方法,這時讀取web.xml配置檔案,完成初始化工作。“https://tigeryoyo.github.io/”是宣告定義在web.xml裡的,用FilterConfig物件可以讀取。
可以看到新增過濾器後,實現了過濾doFilterTest.jsp訪問的請求,並將該請求處理為對百度首頁的訪問。控制檯資訊也表明,實現過濾器後,對doFilterTest.jsp訪問時候,先進入了過濾器TestFilter類的doFilter()方法。