17

对于所有“重复”的狂热分子,这里有一个关于 SO 的类似问题。不同之处在于我画了一个我无法理解输出的生动示例。

JspWriterPrintWriter的文档说有两个区别:1. JspWriter 可以抛出异常, PrintWriter 不应该这样做。2. JspWriter 在后台使用 PrintWriter,但由于默认情况下 JSP 页面是缓冲的,因此不会创建 PrintWriter 直到the buffer is flushed- 无论在 JSP 页面的上下文中意味着什么。我不确定我是否理解了最后一部分。考虑这个 JSP 页面:

<%@page import="java.io.PrintWriter"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JspWriter versus PrintWriter</title>
    </head>
    <body>
        <p>I should be row one.</p>
        <%
            out.println("<p>JspWriter said: I should be the second row.</p>");

            PrintWriter pw = response.getWriter();
            pw.println("<p>PrintWriter said: I should be the third row.</p>");
        %>
        <p>I should be the fourth row.</p>
    </body>
</html>

它产生以下输出:

PrintWriter said: I should be the third row.
I should be row one.
JspWriter said: I should be the second row.
I should be the fourth row.

如您所见,JspWriter 按照我的预期将他的字符串输出到浏览器。但是 PrintWriter 在所有其他内容发送到浏览器之前输出他的字符串。如果我们检查发送到浏览器的源代码,PrintWriter 的字符串作为第一行发送,在 DOCTYPE 声明之前。那么在上面的例子中,究竟发生了什么?

4

2 回答 2

17

解释在您自己的问题中:

JspWriter 在后台使用 PrintWriter,但由于默认情况下 JSP 页面是缓冲的,因此在刷新缓冲区之前不会创建 PrintWriter

这意味着写入 JspWriter 的内容被缓冲,一旦这个缓冲区被刷新(因为缓冲区已满,或者因为 JSP 已到达其执行的末尾),内容将被写入响应的 PrintWriter。

因此,您的示例流程如下:

  • 直到 scriptlet 的静态 HTML 代码:写入内存缓冲区
  • out.println(...):写入内存缓冲区
  • pw.println(...):写入响应
  • 直到 JSP 结束的静态 HTML 代码:写入内存缓冲区
  • 内存缓冲区的刷新:它包含的所有内容都写入响应
于 2012-11-02T19:03:00.053 回答
0

JSP 应该使用由“out”隐式对象表示的 JspWriter 将输出发送回客户端。JspWriter 是 PrintWriter 的缓冲版本。有关详细信息,请参阅 JspWriter API。JspWriter 与 PrintWriter 的区别还在于抛出 java.io.IOException,而 PrintWriter 不会。

于 2013-10-19T11:58:04.887 回答