过滤器链(Filter Chain)是 Java Servlet 规范中定义的一种机制,它用于在 Servlet 处理请求之前或之后对请求进行过滤和处理。过滤器链是由多个过滤器组成的,每个过滤器都可以对请求进行处理并将处理后的请求传递给下一个过滤器,直到最后一个过滤器将处理后的请求传递给 Servlet 进行处理。在 Servlet 处理完请求后,响应会被传递回来,并按照相反的顺序经过过滤器链的每个过滤器进行处理。因此,过滤器链的顺序非常重要,不同的顺序可能会导致不同的结果。
下面是一个使用过滤器链的例子,假设我们需要对所有的请求进行权限验证并进行日志记录,我们可以编写两个过滤器,一个用于权限验证,一个用于日志记录:
1.权限验证过滤器 AuthFilter
public class AuthFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 进行权限验证
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession();
String username = (String) session.getAttribute("username");
if (username != null && !username.isEmpty()) {
// 如果用户已登录,则允许通过
chain.doFilter(request, response);
} else {
// 如果用户未登录,则重定向到登录页面
resp.sendRedirect("login.jsp");
}
}
@Override
public void destroy() {
// 销毁操作
}
}
2.日志记录过滤器 LogFilter
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 进行日志记录
System.out.println("Request URL: " + ((HttpServletRequest) request).getRequestURL());
// 将请求传递给下一个过滤器
chain.doFilter(request, response);
// 处理响应
System.out.println("Response Status Code: " + ((HttpServletResponse) response).getStatus());
}
@Override
public void destroy() {
// 销毁操作
}
}
接下来,我们需要将这两个过滤器组合成一个过滤器链,并将该过滤器链配置到我们的 Web 应用中。在 web.xml 文件中添加如下配置:
<filter>
<filter-name>authFilter</filter-name>
<filter-class>com.example.AuthFilter</filter-class>
</filter>
<filter>
<filter-name>logFilter</filter-name>
<filter-class>com.example.LogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>logFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这里定义了两个过滤器和两个过滤器映射,其中 authFilter 和 logFilter 是过滤器的名称,com.example.AuthFilter 和 com.example.LogFilter 分别是两个过滤器的实现类。过滤器映射将过滤器和 URL 模式进行绑定,表示只要是以 /* 开头的 URL 都会经过这两个过滤器处理。
上面的例子中,所有的请求都会先经过 AuthFilter 进行权限验证,如果用户已登录则允许通过,否则重定向到登录页面。然后请求会经过 LogFilter 进行日志记录,并传递给下一个过滤器。在 Servlet 处理完请求后,响应会按照相反的顺序经过过滤器链的每个过滤器进行处理,最终返回给用户。
注意:过滤器链是按照过滤器配置的顺序进行处理的,如果需要改变过滤器顺序,可以调整过滤器的配置顺序。