在 Servlet 中,过滤器(Filter)是一种用于在请求到达 Servlet 或响应返回到客户端之前进行处理的机制。过滤器可以用于多种功能,如身份验证、日志记录、性能监控、输入输出编码转换等。
过滤器是一个接口,允许我们在请求和响应链中对请求进行处理或者修改响应。过滤器可以在请求到达 Servlet 前、响应返回客户端前对请求和响应进行处理。
过滤器本身不能直接处理请求和响应,而是通过 doFilter()
方法来传递请求和响应对象。通过这个方法,过滤器可以对请求和响应做修改或在请求/响应链中传递给下一个过滤器或者 Servlet。
过滤器有如下生命周期方法:
init()
: 初始化过滤器。此方法在过滤器实例化后,doFilter()
方法之前调用一次。可以用于一些初始化工作。doFilter()
: 每次请求都会调用此方法。在此方法中,过滤器可以对请求和响应进行操作。此方法接收 ServletRequest
和 ServletResponse
对象,并且需要调用 chain.doFilter()
来传递请求和响应。destroy()
: 销毁过滤器。过滤器销毁前会调用此方法,适用于一些资源的释放。首先创建一个过滤器类,继承 javax.servlet.Filter
接口并实现 doFilter()
方法。以下是一个简单的过滤器示例:
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/example/*") // 通过注解来配置过滤器,指定过滤的URL路径
public class ExampleFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter initialized.");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Filter applied to request.");
// 可以在这里对请求进行修改,或者进行额外的操作(如日志记录)
// 继续调用下一个过滤器或目标 Servlet
chain.doFilter(request, response);
System.out.println("Filter applied to response.");
// 可以在这里对响应进行修改,或者进行额外的操作
}
@Override
public void destroy() {
System.out.println("Filter destroyed.");
}
}
这个过滤器对路径 /example/*
的请求进行过滤。在 doFilter()
方法中,你可以添加自己的业务逻辑来处理请求或响应。
上面的示例已经使用了 @WebFilter
注解来配置过滤器。通过这种方式,你可以在 web.xml
中不再进行配置,直接通过注解进行。
你可以配置以下属性:
urlPatterns
:指定过滤器拦截的 URL 路径模式。initParams
:传递过滤器的初始化参数。filterName
:指定过滤器的名称(可选)。web.xml
配置过滤器如果不想使用注解,可以通过 web.xml
配置过滤器。以下是如何在 web.xml
中配置过滤器:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>exampleFilterfilter-name>
<filter-class>com.example.filters.ExampleFilterfilter-class>
filter>
<filter-mapping>
<filter-name>exampleFilterfilter-name>
<url-pattern>/example/*url-pattern>
filter-mapping>
web-app>
在 web.xml
中配置了
和
元素:
元素指定了过滤器的名称和类。
元素指定了过滤器的映射路径,/example/*
表示拦截 /example/
路径下的所有请求。过滤器链是一个 FilterChain
对象,用于在多个过滤器之间传递请求。FilterChain
中的 doFilter()
方法是关键,它将请求和响应对象传递给下一个过滤器或 Servlet。
例如,在一个应用程序中,可以配置多个过滤器,每个过滤器都执行某些操作,然后将请求交给下一个过滤器或者最终的 Servlet。
@WebFilter("/example/*")
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Request received at " + System.currentTimeMillis());
// 继续调用下一个过滤器
chain.doFilter(request, response);
System.out.println("Response sent at " + System.currentTimeMillis());
}
}
在这个示例中,LoggingFilter
会记录请求的时间。chain.doFilter(request, response)
将请求传递给下一个过滤器或目标 Servlet。
身份认证和授权:
使用过滤器检查用户是否已登录或授权访问某些资源。
@WebFilter("/secure/*")
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (httpRequest.getSession().getAttribute("user") == null) {
response.getWriter().write("User is not authenticated!");
return;
}
chain.doFilter(request, response); // 用户已认证,继续处理请求
}
}
日志记录:
记录请求和响应的相关信息,便于调试和监控。
性能监控:
记录请求处理的时间,帮助分析应用的性能瓶颈。
输入输出编码转换:
在请求或响应时,进行字符编码的转换,确保数据的正确性。
过滤器是 Servlet 技术中非常强大的功能之一。通过过滤器,开发人员可以在请求到达 Servlet 或响应返回客户端之前,进行各种操作,如日志记录、性能监控、身份验证等。过滤器既可以使用注解方式配置,也可以通过 web.xml
配置。理解和掌握过滤器的使用,对于开发企业级 Web 应用非常重要。