Web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
Filter译为过滤器。 由于 Servlet 规范是开放的,借助于公众与开源社区的力量, Servlet 规范越来越科学,功能也越来越强大。 2000 年, Sun 公司在 Servlet2.3 规范中添加了 Filter 功能,并在 Servlet2.4 中对 Filter 进行了细节上的补充。
过滤器的作用:
- 一般用来完成通用操作,比如登录验证、统一编码设置、敏感字符过滤等
一、过滤器的运行原理
当客户端向服务器端发送一个请求时,如果有对应的过滤器进行拦截,过滤器可以改变请求的内容、或者重新设置请求协议的相关信息等,然后再将请求发送给服务器端的Servlet进行处理。当Servlet对客户端做出响应时,过滤器同样可以进行拦截,将响应内容进行修改或者重新设置后,再响应给客户端浏览器。在上述过程中,客户端与服务器端并不需要知道过滤器的存在。
在一个Web应用程序中,可以部署多个过滤器进行拦截,这些过滤器组成了一个过滤器链。过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到服务器端的Servlet。
二、过滤器的使用
1、使用步骤(来回都要过滤)
- 定义一个类,实现接口Filter
- 重写内部方法(init、doFilter、destory)
- 配置拦截路径(配置方法1:注解 @WebFilter、配置方法2:web.xml方法)
- 注:做好过滤后,需要做放行处理:filterChain.doFilter(servletRequest, servletResponse);
2、字符编码设置过滤器
package com.test.web.myFilter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("*")
public class charSetFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//设置统一字符编码
servletRequest.setCharacterEncoding("UTF-8");
//转发到对应的servlet
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
三、过滤器细节
1、web.xml配置方式(麻烦)
<!-- 在web.xml中配置Filter-->
<filter>
<filter-name>demo1</filter-name>
<filter-class>com.test.web.myFilter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
2、过滤器执行流程
请求和回应都需要经过过滤器,因此过滤器来去都需要经过。
- 注:过滤器中执行的界限是放行操作filterChain.doFilter,请求执行放行操作前的代码,回应执行放行操作后的代码
3、过滤器的生命周期方法
package com.test.web.myFilter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("*")
public class FilterDemo implements Filter {
/**
* 在服务器启动后,会创建Filter对象,然后调用init方法
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 每次请求被拦截资源时会被执行,执行多次
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
/**
* 在服务器关闭后,filter对象被销毁,如果服务器正常关闭,则会执行destroy方法
*/
@Override
public void destroy() {
}
}
4、过滤器配置详解
(1)拦截路径的配置
- 具体的资源路径,如:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 目录拦截,如:/user/* 访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截,如:*.jsp 访问所有的后缀名为jsp资源时,过滤器都会被执行
- 拦截所有资源,如: * 拦截所有的资源,过滤器都会被执行
(2)拦截方式的配置
拦截方式:指的是资源被访问的方式
配置方式:
- 1、注解配置:设置dispatcherTypes属性,值为:
- REQUEST:默认值,浏览器直接请求资源
- FORWARD:转发来访问资源(此时直接访问时就不会执行过滤器)
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
- 注:dispatcherTypes在代码中是一个数组配置,所以该值可以配置多个,使用“{}”包裹
语法:@WebFilter(value = "*", dispatcherTypes = DispatcherType.REQUEST)
- 2、web.xml配置
- 设置一个标签即可:<dispatcher>REQUEST</dispatcher>
5、过滤器链(配置多个过滤器)
在一个项目中配置多个过滤器,定义好各个过滤器之间的执行顺序
过滤器的先后顺序问题:
- 注解配置的过滤器:按照类名的字符串比较规则比较,值小的先执行
- 如:AFilter 和 BFilter 此时就是AFilter先执行
- web.xml配置的过滤器:谁定在web.xml文件中的前面谁先执行(书写顺序)