isReady() 在关闭状态下返回 true - 为什么?



ServletOutputStream.isReady()javadoc 说:

返回: 如果对此 ServletOutputStream 的写入成功,则为 true,否则返回 false。

尽管 Jetty 的实现ServletOutputStream,但在流处于CLOSED状态的情况下,HttpOutput似乎表现得相当混乱。它返回true

case CLOSED:
return true;

来源:HttpOutput.java:1011。

此外,HttpOutput中的所有三种write方法在CLOSED时都会抛出EofException

case CLOSED:
throw new EofException("Closed");

所以看来写永远不可能成功。这种行为背后的原因是什么?

关键事实:关闭调用意味着写入操作。

CLOSED内部状态表示流/输出的使用对该调度是 CLOSED 的(而不是流本身实际上已关闭(。

我们是如何进入这种状态的?某些东西触发了ServletOutputStream.close()(反过来又HttpOutput.close()(,现在不允许从当前调度对该流进行更多写入。

在"已关闭"状态下,将发生刷新。

  • 刷新将提交响应
  • 刷新将完成写入交换/连接/输出的各个层上存在的各种缓冲区。
  • 如果有一个聚合缓冲区(对于许多小写入(,它会将其写出。
  • 如果有压缩层(gzip(,它也将强制从那里刷新。
  • 然后所有这些缓冲区也通过Transfer-Encoding层(例如:分块(。
  • 然后进行网络写入。

HttpOutput也是所有嵌套请求的一个输出点,例如使用RequestDispatcher中的include(),这将重新打开HttpOutput以供include()期间使用,然后再次关闭它。

一旦HttpOutput完全刷新/完成(不再调度,不再写入等(,则完成最终缓冲区刷新,完成传输编码,重置,回收HttpOutput,并返回到HttpConnection以供下一次交换使用。

我们可以在代码库中更好地处理javadoc,或者至少使用更有意义的常量和变量名称。

已打开 https://github.com/eclipse/jetty.project/issues/2687

关于码头EofException(不是JVMEOFException(写入。

一旦ServletOutputStream关闭以用于特定派送,进一步拨打write()将导致码头EofException

还有一种EofException,违反了您提交的响应详细信息。

例如:您声明了一个Content-Length40MB 的响应,但写入了 41MB,您超出了该提交响应的能力,这是一个 IOException。Servlet 规范告诉我们在这种情况下抛出一个IOException

Jetty将抛出 Jetty 内部EofException(扩展 IOException(以指示此特定方案并中止连接,从而中断您可能想要的任何连接持久性。

相关内容

  • 没有找到相关文章

最新更新