什么是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()方法。