call 和有什么区别:
res.flushBuffer();
相对
res.getOutputStream().flush();
这些方法是否刷新相同的缓冲区?
如果是这样,你能给我一个关于 servlet 容器如何管理这个缓冲区的线索吗?
call 和有什么区别:
res.flushBuffer();
相对
res.getOutputStream().flush();
这些方法是否刷新相同的缓冲区?
如果是这样,你能给我一个关于 servlet 容器如何管理这个缓冲区的线索吗?
打电话有什么区别...
唯一显着的区别是,无论您是以文本模式还是二进制模式编写/打算编写正文,第一个版本都可以使用,而第二个版本仅适用于二进制模式输出。
这些方法是否刷新相同的缓冲区?
由于 javadocs 没有给出明确的答案,因此从技术上讲,它取决于实现。然而,在实践中,大多数实现的答案可能是“是”,因为很难想象拥有单独的缓冲区是有意义的。
在 javadoc 中有一些间接证据:
javadoc for说:“设置响应正文的setBufferSize(int)
首选缓冲区大小。” 这意味着这个缓冲区与 javadoc 中提到的“缓冲区”相同。flushBuffer()
javadoc forflushBuffer()
说:“调用此方法会自动提交响应,这意味着将写入状态代码和标头。” ...这与一个模型一致,即所有事物都有效地使用一个缓冲区。
要注意的另一件事是,servlet 看到的响应对象实际上可能是一个特定于应用程序的包装器,它被插入到过滤器链的更深处。这种包装器的行为方式可能与 javadoc(以及 servlet 规范的其余部分)所说的不一致。
如果是这样,你能给我一个关于 servlet 容器如何管理这个缓冲区的线索吗?
最好的办法是查看容器的源代码。
如果您一直在使用getOutputStream
写入正文,它们将刷新相同的缓冲区。另一种选择是getWriter
用于非二进制数据。如果您一直在使用它,那么调用res.getOutputStream().flush();
可能不起作用。
管理缓冲区的方式是特定于实现的,但以Tomcat 实现之一为例。可以看到有一些字段是这样的:
/**
* The associated output buffer.
*/
protected OutputBuffer outputBuffer;
/**
* The associated output stream.
*/
protected CoyoteOutputStream outputStream;
/**
* The associated writer.
*/
protected CoyoteWriter writer;
调用getOutputStream()
创建 a CoyoteOutputStream
,它使用outputBuffer
那里显示的字段,同样适用于getWriter()
。所以他们都会outputBuffer
根据你使用的来使用它。flushBuffer
只是这样做:
@Override
public void flushBuffer()
throws IOException {
outputBuffer.flush();
}