大可制作:QQ群:31564239(asp|jsp|php|mysql)

JSP/Servlet: out

在之前撰写JSP的例子中,使用了out这个对象,这个对象您不用事先声明,就可以在JSP网页中使用,这是 JSP所提供的隐含对象(Implicit Object),在转译为Servlet之后,out会转换为对应于javax.servlet.jsp.JspWriter类型的对象。

JspWriter直接继承自java.io.Writer,您可以使用println()、print()方法将指定的数据以字节的方式传送至客户端, println()会在送出数据之后进行换行,而print()则否,注意换行指的是在HTML原始码中设定换行字节,而不是输出<br>标 签使得在网页中可以换行。

out(JspWriter)具有缓冲区功能,HTTP的特性是为了要取得一份资源,就进行一份协定沟通,如果资源数目很多(例如一份 HTML文件中还包括了许多的小图片),而每份资源的容量实际上很小,那么为了要取得完整的资源,将会花费很多通讯在协定往来上,假设如果out (JspWriter)不具有缓冲功能,则每一次out.println(),就会直接将数据送出至客户端,那么单要完成一个完整网页的传送,就会花费不 少的网路资源,每一个JSP网页默认上都会具有缓冲,您可以使用page指令元素的autoFlush属性来设定是否使用缓冲区功能。

在Tomcat 5上,默认为每一个JSP网页备有8192位元组的缓冲区(您可以使用page指令元素的buffer属性来自定缓冲区的大小),在缓冲区还没有满之前,数据不会真正被送出至客户端,在这之前,您还有机会重设送出的数据,如果缓冲区满了,数据将会被出清并送至客户端,可以使用下面这个程序来示范:

  • buffer.jsp
<%@page contentType="text/html;charset=Big5"%> 
<%
out.println("默认缓冲区大小: " +
out.getBufferSize() + "<br>");
out.flush();

// 下面的文字不会出现在客户端
out.println("您看的到这段文字吗?");
out.clearBuffer();

out.println("这段您可以看到!");
%>

您可以使用flush()直接出清缓冲区的内容,而clearBuffer()会将缓冲区的内容清除,所以第二段文字不会出现在客户端的网页上,而最后一段会在整个JSP网页执行完后自动送出至客户端,执行结果如下:
默认缓冲区大小: 8192
这段您可以看到!
 
您可以使用page指令元素的autoFlush来设定JSP页面是否使用缓冲区自动出清功能,out(JspWriter)以一种方式与 HttpServletResponse的PrintWriter建立关系,两者之间的行为关系取决于是否使用缓冲区自动出清,如果使用缓冲区自动出清, 则在缓冲区满之前,或是使用flush()之前不会建立PrintWriter对象来对客户端进行输出,如果不使用缓冲区自动出清,则写入 out(JspWriter)对象的数据会直接写入PrintWriter对象,然后在指定flush()之后输出至客户端。

如果您将autoFlush设定为false,则您必须明确的使用flush()来输出数据,否则缓冲区满了的话,就会发生 IOException异常,使用缓冲区有其好处,但由于缓冲区在满之前,数据并不会真正送出客户端,所以会有回应延迟的问题,如果您要即时性将结果回应 至客户端,则可以关闭缓冲区。

下面这个程序测试缓冲区关闭之后,如果缓冲区满了,会有什么结果:

  • buffer.jsp
<%@page contentType="text/html;charset=Big5" 
autoFlush="false"%>
<%
for(int i = 0; i < 2000; i++) {
out.println("test");
//out.flush();
}
%>

如果没有移开out.flush()的注释符号,则会回应以下的错误讯息:
HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.io.IOException: Error: JSP Buffer overflow
......