在之前撰写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 ......