前言
JavaWeb 中的过滤器(Filter)是一种重要的组件,用于对请求和响应进行过滤和处理。它可以在请求进入 Servlet 之前进行预处理,也可以在响应返回客户端之前进行后处理。过滤器通常用于执行一些共享的任务,如身份验证、日志记录、字符编码转换等,以提高应用程序的可维护性和可重用性。
情景引入
假设你正在开发一个电子商务网站。你想要对所有的请求进行身份验证,以确保只有经过身份验证的用户可以访问敏感信息,比如订单详情或个人信息。这时候,你可以创建一个过滤器来处理身份验证逻辑。
为什么要用过滤器呢?
如果没有过滤器,一些常见的任务,如身份验证、日志记录、字符编码转换等,需要在每个Servlet或处理请求的地方进行手动处理。这会导致代码重复和冗余,降低代码的可维护性和可读性。
人总有粗心的时候,如果某个地方没有进行手动处理,就可能会造成敏感信息泄露的问题,造成不必要的损失。
通俗点来讲,就是自己写更麻烦,而且后期的维护和拓展也会更难,有现成的封装为什么不用呢?
模拟实现
一般写到过滤器,项目已经基本成型,我还写不出真正的项目,所以只能这样解释了
创建接口类
首先,创建一个 Java 类来实现过滤器接口。过滤器接口有三个方法:init(), doFilter(), 和 destroy()。通常,我们只需要实现 doFilter() 方法,它包含了实际的过滤逻辑。
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
// 初始化代码,可以在这里读取配置信息等
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 这里编写过滤逻辑,对请求进行处理
// 例如,可以进行身份验证、日志记录、字符编码转换等操作
// 继续将请求传递给下一个过滤器或 Servlet
chain.doFilter(request, response);
// 在响应返回客户端之前,可以进行后处理操作
}
public void destroy() {
// 在销毁过滤器时执行清理工作
}
}
Filter接口定义了三个方法:
这也叫过滤器的生命周期
init()方法
:该方法在Filter启动时被调用,用于初始化Filter。
doFilter()方法
:该方法在每次HTTP请求被处理时被调用,用于对请求进行处理,并将请求传递给下一个Filter或Servlet处理。
destroy()方法
:该方法在Filter关闭时被调用,用于清理资源。
配置过滤器
使用Filter需要在web.xml中进行配置。例如,下面的配置将一个名为MyFilter的Filter映射到所有的HTTP请求上。
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<!-- 这个url-pattern是用来指定拦截路径的-->
<url-pattern>/secured/*</url-pattern>
</filter-mapping>
上述配置表示 MyFilter 过滤器会拦截以 /secured/ 开头的 URL。你可以根据你的需求更改 url-pattern。
在SpringBoot项目中,配置有所区别但原理相同,更多需要注意的是那些烦人的注解,当然我现在还没实际应用过,之后再写。
过滤器链
过滤器链(Filter Chain)是指一系列的Filter按照一定的顺序依次处理HTTP请求和响应的过程。当客户端发送HTTP请求时,请求首先会经过第一个Filter进行处理,然后将处理后的请求传递给下一个Filter进行处理,最终传递给Servlet进行处理。在响应返回客户端时,响应也会经过一系列Filter进行处理,最终返回给客户端。
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/path1/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/path1/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Filter3</filter-name>
<url-pattern>/path2/*</url-pattern>
</filter-mapping>
上面的配置表示,对于所有匹配"/path1/“的请求,会先经过Filter1处理,然后经过Filter2处理。对于匹配”/path2/"的请求,会经过Filter3处理。这样就形成了一个简单的过滤器链。
在过滤器链的处理过程中,如果其中一个Filter出现了异常或中断了请求的处理,处理流程会直接跳转到响应处理的阶段,直接返回给客户端。因此,过滤器链的顺序非常重要,不同的顺序可能会产生不同的结果。
总结
总之,过滤器是在请求进入 Servlet 之前进行预处理,或者在响应返回客户端之前进行后处理的组件。它们可以用于各种任务,如身份验证、日志记录、字符编码转换等。通过使用过滤器,你可以增强网站的安全性、可维护性和可重用性。