比如标题
@WebFilter("/*")
@Component
@Slf4j
public class FilterDemo1 implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException, IOException {
new Thread(() -> {
try {
chain.doFilter(req, resp);
} catch (Exception e) {
log.error("a", e);
}
}).start();
}
}
因此,如果tomcat筛选器中有耗时的任务(如rpc或http),它们必须等待并且不能是异步的
java.lang.NullPointerException: null
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]```
[error][1]
[1]: https://i.stack.imgur.com/tFYTH.png
1条答案
按热度按时间kzipqqlq1#
这个
ServletRequest
,ServletResponse
及FilterChain
对象仅在以下线程上有效:doFilter
被称为。如果希望异步使用它们,则需要启用异步处理(参见jakarta ee教程)。ServletRequest.startAsync()
把ServletRequest
及ServletResponse
进入异步模式,但FilterChain
只能在原始螺纹上使用:这个
service
方法必须与应用于servlet的所有筛选器在同一线程中运行。(参见servlet规范)
因此,您需要按照以下步骤进行操作:
当一个新请求通过过滤器时,您调用
ServletRequest.startAsync()
并启动新线程或使用任何其他执行器进行异步筛选(例如。AsyncContext.start(Runnable)
),异步任务完成后,将结果写入请求属性并调用
AsyncContext.dispatch()
:这将从一开始重新启动过滤器链,什么时候
doFilter
再次调用时,使用请求的属性执行过滤逻辑并调用FilterChain.doFilter
例如,您可以使用如下内容: