一、Filter传递
假设有3个 Filter,分别为Filter1~3,顺序依次为 1、2、3(即 1 在最前,3 在最后),具体代码示例如下:
import jakarta.servlet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
@Order(1)
public class Filter1 implements Filter {
private static final Logger log = LoggerFactory.getLogger(Filter1.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("Filter1 Before");
chain.doFilter(request, response);
log.info("Filter1 After");
}
}
---
@Component
@Order(2)
public class Filter2 implements Filter {
private static final Logger log = LoggerFactory.getLogger(Filter2.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("Filter2 Before");
chain.doFilter(request, response);
log.info("Filter2 After");
}
}
---
@Component
@Order(3)
public class Filter3 implements Filter {
private static final Logger log = LoggerFactory.getLogger(Filter3.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("Filter3 Before");
chain.doFilter(request, response);
log.info("Filter3 After");
}
}
它们的 doFilter 执行顺序如下:
- 请求进入时,先执行 Filter1 的 doFilter 方法。
- 在 Filter1 的 chain.doFilter(request, response) 处,进入 Filter2 的 doFilter。
- 在 Filter2 的 chain.doFilter(request, response) 处,进入 Filter3 的 doFilter。
- 在 Filter3 的 chain.doFilter(request, response) 处,进入目标 Servlet。
- Servlet 处理完后,依次返回到 Filter3、Filter2、Filter1,执行它们在 chain.doFilter 之后的代码。
总结:
- 进入顺序:Filter1 → Filter2 → Filter3 → Servlet
- 返回顺序:Filter3 → Filter2 → Filter1
- 即“先进后出”。
具体的执行日志如下:
Filter1 Before
Filter2 Before
Filter3 Before
Filter3 After
Filter2 After
Filter1 After
二、Filter短路
如果在 Filter2 的 doFilter 方法中没有调用 chain.doFilter(request, response),则请求处理流程会在 Filter2 停止,不会进入 Filter3 和目标 Servlet。
Filter2的代码调整如下:
import jakarta.servlet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
@Order(2)
public class Filter2 implements Filter {
private static final Logger log = LoggerFactory.getLogger(Filter2.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("Filter2 Before");
//chain.doFilter(request, response);
//log.info("Filter2 After");
}
}
执行顺序如下:
- 进入 Filter1 的 doFilter,调用 chain.doFilter,进入 Filter2。
- 进入 Filter2 的 doFilter,未调用 chain.doFilter,流程在此终止。
- Filter3 和 Servlet 都不会被执行。
- 返回时,直接回到Filter2之前的Filter,此时仅有 Filter1(亦可以存在多个前置Filter),执行前置Filter在 chain.doFilter 之后的代码(如果有)。
总结:
- 只会执行到 Filter2,Filter3 及后续 Servlet 不会被调用。
- 这种写法常用于拦截、短路请求等场景。
具体的执行日志如下:
Filter1 Before
Filter2 Before
Filter1 After
1336

被折叠的 条评论
为什么被折叠?



