Filter过滤器
1.Filter概念
[!TIP]
在JavaEE中,过滤器(Filter)是一种用于拦截HTTP请求和响应的组件。它们可以在请求到达Servlet之前对请求进行预处理,也可以在响应发送到客户端之前对响应进行后处理。
- Filter过滤器是JavaEE规范,也就是接口
- Filter过滤器它的作用是,拦截请求,过滤响应
2.过滤器的工作原理
-
客户端发送HTTP请求。
-
请求到达Web服务器,首先被过滤器拦截。
-
过滤器可以对请求进行预处理,也可以直接放行。
-
如果有多个过滤器,它们按照在web.xml文件中或使用注解的顺序依次执行。
-
请求被发送到目标Servlet或JSP页面。
-
目标Servlet处理请求并生成响应。
-
响应返回到过滤器。
-
过滤器可以对响应进行后处理,也可以直接放行。
-
如果有多个过滤器,它们按照相反的顺序执行。
-
最终,响应被发送到客户端。
3.过滤器的功能
-
身份验证和授权:过滤器可以验证用户的身份,并根据权限决定是否允许访问受保护资源。
-
日志记录:过滤器可以记录请求和响应的详细信息,用于调试和性能监控。
-
数据压缩和解压缩:过滤器可以在服务器端对响应数据进行压缩,以减少网络带宽和提高网站性能。
-
安全防护:过滤器可以检查请求和响应中的恶意内容,如XSS和CSRF攻击,并进行相应的防护。
-
请求转发和重定向:过滤器可以拦截请求并进行重定向或转发到其他资源,实现URL重写和路由功能。
-
资源过滤和转换:过滤器可以在服务器端对请求的资源进行过滤和转换,如图片水印、HTML压缩等。
4.过滤器的生命周期
生命周期方法 | 被调用时机 |
---|---|
1.构造方法 | web工程启动时调用,当过滤器对象被实例化时调用。 |
2.init(FilterConfig) | web工程启动时调用,在过滤器被初始化时调用,执行一次性初始化操作。 |
3.doFilter(…) | 每次处理请求时被调用,用于执行过滤逻辑。 |
4.destroy() | 停止web工程的时候调用,在过滤器被销毁时调用,执行清理操作。 |
5.FilterConfig类
[!tip]
Filter过滤器的配置文件类
Tomcat容器每次创建Filter的时候,也会同时创建一个FilterConfig类,包含了Filter配置文件的配置信息。
[!note]
作用:
1.获取Filter的名称filter-name内容
2.获取Filter中配置的init-param初始化参数
3.获取ServletContext对象
方法 | 描述 |
---|---|
String getFilterName() | 返回过滤器的名称。 |
String getInitParameter(String name) | 根据给定的参数名称返回对应的初始化参数值。 |
Enumeration<String> getInitParameterNames() | 返回过滤器的所有初始化参数的名称的枚举。 |
ServletContext getServletContext() | 返回与过滤器关联的ServletContext对象,可以用于获取Web应用的全局信息。 |
6.过滤器的两种配置方式
过滤器可以通过web.xml文件或使用注解进行配置。
-
使用注解:
-
使用注解是自JavaEE 6以来的一种新方式。通过在过滤器类上添加
@WebFilter
注解,可以直接在过滤器类中定义过滤器的配置信息,而无需修改web.xml
文件。这种方式简化了配置流程,使得配置更加直观和简洁。 -
注解方式的优点包括:
- 简洁性:所有配置信息都集中在过滤器类的注解中,使得代码更加清晰和易于维护。
- 直观性:通过注解直接在代码中定义配置信息,更容易理解和调整过滤器的行为。
- 灵活性:可以直接在过滤器类中修改配置信息,无需修改
web.xml
文件,提高了灵活性和便捷性。
-
示例:
import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import javax.servlet.Filter; @WebFilter(filterName = "MyFilter", urlPatterns = {"/*"}, initParams = { @WebInitParam(name = "paramName", value = "paramValue") }) public class MyFilter implements Filter { // 过滤器实现代码 }
-
在上面的示例中,通过
@WebFilter
注解指定了过滤器的名称为"MyFilter",URL模式为"/*“(匹配所有请求),并指定了一个初始化参数"name"为"paramName”,值为"paramValue"。
属性 说明 filterName 过滤器的名称。 value 与 urlPatterns
相同,用于指定要拦截的URL模式。urlPatterns 过滤器所要拦截的URL模式。 servletNames 过滤器所要拦截的Servlet名称。 dispatcherTypes 过滤器的调度器类型,指定过滤器在何种情况下会被调用。 initParams 过滤器的初始化参数数组,用于指定过滤器的初始化参数。 asyncSupported 表示过滤器是否支持异步操作。 description 过滤器的描述信息。 -
-
使用web.xml文件配置:
-
这是一种传统的配置方式,在JavaEE早期版本就已经存在。通过修改
web.xml
文件,可以为过滤器定义各种配置信息,包括过滤器名称、URL模式、初始化参数等。 -
使用
web.xml
文件配置过滤器的优点包括:- 兼容性:
web.xml
文件是JavaEE应用程序配置的标准方式,兼容性好,适用于各种JavaEE版本。 - 灵活性:可以通过XML配置文件灵活地定义各种复杂的过滤器配置,满足不同场景下的需求。
- 可读性:配置信息以XML格式呈现,使得配置结构清晰可见,便于理解和修改。
- 兼容性:
-
示例:
<filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> <init-param> <param-name>paramName</param-name> <param-value>paramValue</param-value> </init-param> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
在上面的示例中,通过XML配置定义了一个名为"MyFilter"的过滤器,指定了过滤器类的完全限定类名,并设置了一个名为"paramName"的初始化参数,值为"paramValue"。同时,通过`
-
[!important]
过滤器的顺序由它们在web.xml文件中的配置顺序或使用注解的顺序决定。通常情况下,过滤器的执行顺序与它们在配置中的顺序一致。
7.FilterChain过滤器链
FilterChain
(过滤器链)是Java Servlet API 中的一个接口,用于将请求传递给过滤器链中的下一个过滤器,或者如果没有下一个过滤器,则将请求传递给目标 Servlet 或 JSP 页面。FilterChain
允许多个过滤器在请求处理过程中依次对请求进行处理,每个过滤器可以选择继续处理请求,将请求传递给下一个过滤器,或者直接将响应发送回客户端。
[!important]
**FilterChain.doFilter()**方法的作用:
1.执行下一个Filter过滤器(如果有Filter)
2.执行目标资源(没有Filter)
1.方法
FilterChain
接口只有一个方法:
doFilter(ServletRequest request, ServletResponse response)
:- 将请求传递给过滤器链中的下一个过滤器,或者如果没有下一个过滤器,则将请求传递给目标 Servlet 或 JSP 页面。
2.作用
-
请求处理链的管理:
FilterChain
允许多个过滤器按照顺序依次处理请求。当一个过滤器的doFilter
方法被调用时,它可以选择继续处理请求,将请求传递给下一个过滤器,或者直接将响应发送回客户端。 -
过滤器链的控制:过滤器可以控制请求是否继续传递给下一个过滤器,或者在什么条件下终止过滤器链的执行。这使得过滤器可以根据特定的条件来决定是否要进行某些处理,或者根据请求和响应的内容来决定如何处理请求。
-
请求和响应的处理:通过
FilterChain
,过滤器可以对请求和响应进行预处理和后处理,例如修改请求参数、记录日志、添加响应头等。
3.示例用法
以下是一个简单的示例,演示了如何在过滤器中使用FilterChain
:
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() {
// 销毁操作
}
}
在上面的示例中,doFilter
方法中的chain.doFilter(request, response)
用于将请求传递给过滤器链中的下一个过滤器,如果没有下一个过滤器,则将请求传递给目标 Servlet 或 JSP 页面。
[!important]
在多个Filter过滤器执行的时候,它们执行的优先顺序是由它们在web.xml中从上到下配置的顺序决定。
[!important]
多个Filter过滤器执行的特点:
- 所有Filter和目标资源默认都执行在同一线程中
- 多个Filter共同执行的时候,它们都使用同一个Request对象
8.Filter过滤器拦截路径
精准匹配: 如果你想要精确匹配某个特定的URL,你可以直接指定该URL作为URL模式。
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/specific/url</url-pattern>
</filter-mapping>
目录匹配:如果你想要匹配某个目录下的所有请求,你可以使用/*
来匹配该目录下的所有URL。
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/directory/*</url-pattern>
</filter-mapping>
后缀名匹配:如果你想要匹配某个特定后缀名的请求,你可以使用通配符*
来匹配。
不要以/开头
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>