文章目录
- 一、过滤器概述
- 1、过滤器的作用
- 2、过滤器的应用场景
- 3、过滤器的工作流程
- 二、过滤器生命周期与方法
- 1、过滤器的生命周期
- 2、过滤器方法
- 3、过滤器的实现步骤
- 三、多个过滤器和 dispatcher
- 1、多个过滤器
- 2、dispatcher
JSP 和 Servlet 中的过滤器都是 Java 类(继承avax.servlet.Filter)。
一、过滤器概述
1、过滤器的作用
过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息,可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
2、过滤器的应用场景
- Web资源权限访问控制
- 请求字符集编码处理
- 内容敏感字符词汇速滤
- 响应信息压缩
3、过滤器的工作流程
过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明,然后映射到应用程序的部署描述符中的 Servlet 名称或 URL 。当 Web 容器启动 Web 应用程序时,它会为您在部署描述符中声明的每一个过滤器创建一个实例。
二、过滤器生命周期与方法
1、过滤器的生命周期
- web应用程序启动时, web服务器创建Filter的实例对象,以及对象的初始化。
- 当请求访问与过滤器关联的Web资源时,过滤器拦截请求,完成指定功能。
- Filter对象创建后会驻留在内存,在web应用移除或服务器停止时才销毁。
- 过滤器的创建和销毁由WEB服务器负责。
2、过滤器方法
方法 | 描述 |
public void init(FilterConfig filterConfig) | web 应用程序启动创建Filter 的实例对象,调用init方法,同时读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(每个filter对象只会创建一次,init方法也只会执行一次)。 |
public void doFilter (ServletRequest, ServletResponse, FilterChain) | 该方法完成实际的过滤操作,当请求访问的url和请求方法与过滤器设置url和方式匹配时,将调用过滤器的doFilter方法。 |
public void destroy() | Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。 |
3、过滤器的实现步骤
- 编写java类实现Filter接口,并实现其doFilter方法。
- 在web.xml文件中对filter类进行注册,并设置所拦截的资源。
- web.xml配置
<!-- 字符集编码过滤器配置 -->
<filter>
<filter-name>characterEncodingFilter</filter-name> <!-- 过滤器的唯一标识 -->
<filter-class>filter.CharacterEncodingFilter</filter-class> <!-- 过滤器执行的类 -->
<init-param> <!-- 过滤器初始化参数,可为多个 -->
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping> <!-- 过滤器映射 -->
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- 对所有的请求进行拦截处理 -->
</filter-mapping>
- 过滤器类
public class CharacterEncodingFilter implements Filter {
private FilterConfig config; // 过滤器配置对象,用于获取配置的参数
public FilterConfig getConfig() {
return config;
}
public void setConfig(FilterConfig config) {
this.config = config;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
System.out.println("CharacterEncodingFilter do init....");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//获取初始参数
String charset = config.getInitParameter("charset");
// 设置请求内容的编码方式
servletRequest.setCharacterEncoding(config.getInitParameter("charset"));
//System.out.println("CharacterEncodingFilter 请求预处理");
// 通知过滤器链这步过滤操作已完成
filterChain.doFilter(servletRequest, servletResponse);
//System.out.println("CharacterEncodingFilter 响应后处理");
}
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter do destroy....");
}
}
三、多个过滤器和 dispatcher
1、多个过滤器
只要像上面完成过滤器类的编写和注册,就可以啦,web服务器会在后台建立过滤器链进行管理。
- 过滤器链
- 在一个web应用中,多个过滤器组合起来称之为一个过滤链。
- 过滤器的调用顺序(预处理顺序)取决于web.xml 中的 filter-mapping 元素的顺序,后处理是其逆序。
2、dispatcher
dispatcher 是 filter-mapping 的子元素,用于指定拦截何种请求方式的url,其设置的值及其含义如下表:
dispatcher设置值 | 描述 |
REQUEST(默认) | 当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。 |
INCLUDE | 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。 |
FORWARD | 如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。 |
ERROR | 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用 |
dispatcher 默认值为 REQUEST ,dispatcher 也可设置为多个已拦截不同形式的访问。
<filter>
<filter-name>testFilter</filter-name>
<filter-class>filter.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>/test2.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
- 测试
<%
//测试dispatcher FORWARD配置
//request.getRequestDispatcher("/test2.jsp").forward(request, response);
//测试dispatcher ERROR配置
//response.sendError(404);
%>
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<!-- 测试dispatcher INCLUDE配置 -->
<jsp:include page="test2.jsp"></jsp:include>
<h1>Test</h1>
</body>
</html>