Servlet过滤器,是一个在Servlet程序之前执行的程序,也就是说,客户端请求先到达Servlet过滤器,通过Servlet过滤器之后,才会进入到具体的Servlet程序里面,执行具体的业务代码。
1.1、过滤器执行顺序
大致执行顺序如下图所示:
1.2、过滤器介绍
为什么需要过滤器呢???过滤器有什么好处呢???
试想一下这种场景,假设我们的Web项目中,有10个Servlet程序,分别处理不同的请求,但是这10个Servlet中,最早执行的代码都需要判断用户是否已经登录了,只有登录之后才可以进行后续的操作,针对这种情况,那我们是不是需要在这10个Servlet程序里面,都写一份判断用户是否登录的代码呢???
当然,在每一个Servlet程序里面都写一份判断用户是否登录的代码,确实可以解决这个问题,但是这种方式太麻烦了,如果工程里面有上百上千个Servlet程序,那可想而知,重复代码得非常多,并且如果要修改用户登录的逻辑,那所有涉及到的代码都需要修改,显然这是不可取的方式。
针对上面这个问题,我们就可以使用Servlet过滤器,Servlet过滤器可以指定拦截哪些Servlet请求,并且所有满足拦截规则的请求,都会先执行Servlet过滤器中的代码,那么就可以在Servlet过滤器里面,编写判断用户是否登录的代码,后续也就只需要维护这一个地方即可,并且不管有多少个Servlet程序,我们始终都只需要维护这个Servlet过滤器的代码。这就是Servlet过滤器的好处之一。
另外,有了过滤器之后,我们也可以在不修改Servlet程序代码的基础之上,对Servlet程序进行功能的增强,例如:添加统一的权限校验功能,统一的日志打印功能等等。
1.3、创建Filter过滤器
要创建Servlet中的过滤器,只需要编写一个类,实现自javax.filter.Filter接口,重写其中的init()、doFilter()、destroy()三个方法即可。
- init()方法是过滤器的初始化方法,该方法只会执行一次,在Tomcat容器启动的时候,Servlet过滤器就会被实例化(new创建对象的时候),此时就会调用init()方法。
- doFilter()方法是Servlet过滤器的业务方法,满足拦截规则的HTTP请求,都将执行doFilter()方法,该方法可以执行多次。
- destroy()方法是过滤器的销毁方法,该方法只会执行一次,在Servlet过滤器被销毁之前,才会调用destroy()方法。
案例代码:
package com.gitcode.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* @version 1.0.0
* @Date: 2024/2/19 20:35
* @Author ZhuYouBin
* @Description: Servlet过滤器
*/
public class FirstFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("执行过滤器的init()初始化方法...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("执行过滤器的doFilter()方法...");
// 放行过滤器,继续执行后续的过滤器
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("执行过滤器的destroy()销毁方法...");
}
}
1.4、创建DemoServlet
为了演示过滤器和Servlet程序的执行顺序,我们这里再创建一个DemoServlet程序,案例代码:
package com.gitcode.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @version 1.0.0
* @Date: 2024/2/19 20:34
* @Author ZhuYouBin
* @Description:
*/
public class DemoServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("执行DemoServlet.service()方法...");
}
}
1.5、web.xml配置过滤器
前面已经创建好了Filter的过滤器代码,但是这个时候,应用程序还不知道有这个过滤器,我们还需要在web.xml配置文件里面,将这个自定义的过滤器配置进去,这样应用程序启动的时候,就会从web.xml配置文件中,对过滤器进行实例化操作,这样我们自定义的过滤器才会真正生效。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee">
<display-name>工程名称</display-name>
<description>
工程描述
</description>
<!-- 配置Servlet -->
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>com.gitcode.servlet.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/demoServlet</url-pattern>
</servlet-mapping>
<!-- 配置过滤器 -->
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>com.gitcode.filter.FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<!-- 拦截 /demoServlet 请求路径 -->
<url-pattern>/demoServlet</url-pattern>
</filter-mapping>
</web-app>
1.6、运行测试
IDEA中启动Tomcat容器,浏览器访问http://localhost:8080/servlet/demoServlet,查看IDEA控制台日志信息,如下所示:
从上图中可以看到,先执行的Servlet过滤器代码,之后再执行的Servlet程序代码,以上就是Servlet过滤器的基本介绍及其使用。
今天就到这里,未完待续~~