Servlet过滤器行为模棱两可?
Posted
技术标签:
【中文标题】Servlet过滤器行为模棱两可?【英文标题】:Servlet Filter acts ambiguously? 【发布时间】:2012-08-14 03:20:18 【问题描述】:在servlet过滤器中,filterChain.doFilter(request, response);应该将请求传递给链中的下一个。 但请考虑以下两个代码: 代码 1:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
filterChain.doFilter(request, response);
try
Thread.sleep(20000);
catch(Exception e)
代码 2:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
try
Thread.sleep(20000);
catch(Exception e)
filterChain.doFilter(request, response);
两个过滤器的执行方式相同。即在服务请求之前两者都需要 20 秒。
但实际上应该发生的是Code1
应该立即发球,Code2
应该在 20 秒后发球。
为什么过滤器会出现这种歧义?
【问题讨论】:
【参考方案1】:在 servlet 或过滤器中休眠总是一个坏主意,因为 HTTP 工作线程是稀缺资源,因此您不应该阻止它们。但在你的具体例子中是有希望的。
基本上,您在 servlet 中打印或过滤到输出的任何内容都会被隐式缓冲以提高性能。如果您在 servlet/filter 中打印足够的数据,则 servlet 容器将刷新缓冲区,并且您的部分响应将到达客户端。但你也可以手动冲洗!
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
filterChain.doFilter(request, response);
response.flushBuffer();
Thread.sleep(20000);
flushBuffer()
指令强制容器刷新输出缓冲区。所有响应标头以及您从 servlet 发送的任何内容都将发送到客户端。但这里有一个问题:客户端将接收数据,但 HTTP 连接在接下来的 20 秒内保持打开状态。我用curl
对此进行了测试,它按预期工作。但是当在浏览器中使用相同的 URL 时(在 Opera、Firefox 和 Google Chrome 上测试),浏览器会等待 20 秒再显示任何内容(这可能取决于您实际发送的内容)。
【讨论】:
您可以通过显式关闭与响应关联的输出流(或写入器)来释放客户端,但我认为这不能保证。以上是关于Servlet过滤器行为模棱两可?的主要内容,如果未能解决你的问题,请参考以下文章