书接上篇博客:多个Filter中doFilter方法的执行顺序(一)
一、Filter异常断链
假设有3个 Filter,分别为Filter1~3,顺序依次为 1、2、3(即 1 在最前,3 在最后),当执行到Filter3时抛出了异常(又或者具体Servlet执行时抛出了异常),具体代码示例如下:
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");
//抛出异常
if (true) {
throw new RuntimeException("Exception in Filter3");
}
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 抛出业务异常,结束Filter3及后续Servlet的执行。
- 无法返回Filter2、Filter1,执行它们在 chain.doFilter 之后的代码。
具体的执行日志如下:
Filter1 Before
Filter2 Before
Filter3 Before
二、Filter异常补偿
如果希望即便后续的Filter或Servlet抛出了异常,优先级更高的Filter的chain.doFilter(request, response) 之后的处理逻辑仍可正常执行,可通过try..finally的形式,调整后的代码如下:
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 {
try {
log.info("Filter1 Before");
chain.doFilter(request, response);
} finally {
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 {
try {
log.info("Filter2 Before");
chain.doFilter(request, response);
} finally {
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 {
try {
log.info("Filter3 Before");
if (true) {
throw new RuntimeException("Exception in Filter3");
}
chain.doFilter(request, response);
} finally {
log.info("Filter3 After");
}
}
}
调整后具体的执行日志如下:
Filter1 Before
Filter2 Before
Filter3 Before
Filter3 After
Filter2 After
Filter1 After
1336

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



