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

标签 java servlets jetty servlet-3.1

ServletOutputStream.isReady() javadoc says the following :

Returns: true if a write to this ServletOutputStream will succeed, otherwise returns false.

尽管 Jetty 的 ServletOutputStream 实现,当流处于 CLOSED 状态时,HttpOutput 似乎表现得相当困惑。它返回true:

case CLOSED:
    return true;

来源:HttpOutput.java:1011 .

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

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

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

最佳答案

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

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

我们是如何进入这种状态的?某些内容触发了 ServletOutputStream.close()(进而触发 HttpOutput.close()),现在不允许从当前调度对该流进行更多写入操作。

在 CLOSED 状态下,会发生刷新。

  • 刷新将提交响应
  • 刷新将完成对交换/连接/输出各层上存在的各种缓冲区的写入。
  • 如果存在聚合缓冲区(用于许多小写入),则会将其写出。
  • 如果有压缩层 (gzip),它也会从那里强制刷新。
  • 然后所有这些缓冲区也会经过传输编码层(例如:分块)。
  • 然后发生网络写入。

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

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

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

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

关于写入时的 Jetty EofException(不是 JVM EOFException)。

一旦 ServletOutputStream 关闭以供特定调度使用,进一步调用 write() 将导致 Jetty EofException

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

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

Jetty 将抛出 Jetty 内部 EofException (它扩展了 IOException)来指示此特定场景并中止连接,从而破坏您可能想要的任何连接持久性。

关于java - isReady() 在关闭状态下返回 true - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51101088/

相关文章:

java - 类型删除和 Flink : what causes run time error?

java - 我应该关闭我的 Spring 3 Controller 的 Writer 参数吗?

java - Jetty 中的 JSR-356 javax websockets(嵌入式和非嵌入式)

java - 使用 Glassfish servlet 配置 Jetty 服务器

java - 如何在同一项目 IntelliJ 中创建多个具有不同 main 的 jar

java - 如何更改 json 对象名称(键)?

java - 给定 BlobstoreService 提供的 HttpServletResponse,如何获取提供的 blob?

java - @WebServlet 与 GlassFish 服务器

java - jetty 6 : static content with directory listing

java - 如何将 Java 对象从 Java 代码转换为 SQL Server 表值参数