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-Length
40MB 的响应,但写入了 41MB,您超出了该提交响应的能力,这是一个 IOException。Servlet 规范告诉我们在这种情况下抛出一个IOException
。
Jetty将抛出 Jetty 内部EofException
(扩展 IOException(以指示此特定方案并中止连接,从而中断您可能想要的任何连接持久性。