4-7 错误处理

通常 JSP 在执行时,在两个阶段下会发生错误。

JSP 网页→ servlet

servlet 类处理每一个请求时

在第一阶段时,产生的错误我们称为Translation Time Processing Errors;在第二阶段时,

产生的错误我们称为Client Request Time Processing Errors。接下来我们将针对这两个阶段产

生错误的原因和处理方法,为各位读者做详细的介绍。

4-7-1 Translation Time Processing Errors

Translation Time Processing Errors 产生的主要原因:我们在撰写JSP时的语法有错误,导

致JSP Container 无法将JSP 网页编译成Servlet 类文件( .class),例如:500 Internal Server

Error,500 是指HTTP 的错误状态码,因此是Server Error,如图4-8。

通常产生这种错误时,可能是JSP 的语法有错误,或是JSP Container 在一开始安装、设定时,

有不适当的情形发生。解决的方法就是再一次检查程序是否有写错的,不然也有可能是JSP

Container 的bug。

图 4-8 500 Internal Server Error

4-7-2 Client Request Time Processing Errors

Client Request Time Processing Errors 错误的发生,往往不是语法错误,而可能是逻辑上

的错误,简单地说,你写一个计算除法的程序,当用户输入的分母为零时,程序会发生错误并抛出

异常(Exception),交由异常处理(Exception Handling)机制做适当的处理。

对于这种错误的处理,我们通常会交给errorPage 去处理。下面举个例子,我想各位读者应该

能够很容易了解。

使用errorPage 的范例程序 (一):ErrorPage.jsp

ErrorPage.jsp

<%@ page contentType="text/html;charset=GB2312" errorPage="Error.jsp" %>

<html>

<head>

<title>CH4 - ErrorPage.jsp</title>

</head>

<body>

<h2>errorPage 的范例程序</h2>

<%!

private double toDouble(String value)

{

return(Double.valueOf(value).doubleValue());

}

%>

<%

double num1 = toDouble(request.getParameter("num1"));

double num2 = toDouble(request.getParameter("num2"));

%>

您传入的两个数字为:<%= num1 %> 和 <%= num2 %><br>

两数相加为 <%= (num1+num2) %>

</body>

</html>

ErrorPage.jsp 程序中,我们使用page 指令中的errorPage 属性,告诉JSP Container,如果

在程序中有错误产生时,会自动交给Error.jsp 处理。

<%@ page contentType="text/html;charset=GB2312 " errorPage="Error.jsp" %>

我们声明一个函数叫toDouble,主要把我们接收进来的字符串转成Double 的类型,才能做加

法运算。

<%!

private double toDouble(String value)

{

return(Double.valueOf(value).doubleValue());

}

%>

接收num1 和num2 两个字符串,并且将它们转为double 的类型,并各自命名为num1 和num2。

<%

double num1 = toDouble(request.getParameter("num1"));

double num2 = toDouble(request.getParameter("num2"));

%>

Error.jsp

<%@ page contentType="text/html;charset=GB2312" isErrorPage="true" %>

<%@ page import="java.io.PrintWriter" %>

<html>

<head>

<title>CH4 - Error.jsp</title>

</head>

<body>

<h2>errorPage 的范例程序</h2>

<p>ErrorPage.jsp 错误产生:<I><%= exception %></I></p><br>

<pre>

问题如下:<% exception.printStackTrace(new PrintWriter(out)); %>

</pre>

</body>

</html>

Error.jsp 主要处理ErrorPage.jsp 所产生的错误,所以在ErrorPage.jsp 中page 指令的属性

errorPage设为Error.jsp,因此,若ErrorPage.jsp有错误发生时,会自动转到Error.jsp来处理。

Error.jsp 必须设定page 指令的属性isErrorPage为true,因为Error.jsp是专门用来处理错

误的网页。

<%@ page contentType="text/html;charset=GB2312" isErrorPage="true" %>

下面这几行代码用来显示出错误发生的原因:

<p>ErrorPage.jsp 错误产生:<I><%= exception %></I></p><br>

<PRE>

问题如下:<% exception.printStackTrace(new PrintWriter(out)); %>

</PRE>

由于在这个程序中并没有做一个窗体来输入两个数字,所以必须手动在URL后输入num1和num2

的值。如图4-9 所示:

图 4-9 ErrorPage.jsp 的执行结果

上一个范例的参数设定为:

http://localhost:8080/JSPBook/CH4/ErrorPage.jsp?num1=100&num2=245

此时num1 的值为100,num2 的值为245,所以相加的结果就为345。但是,如果num1 或num2

的参数不是数字的话,例如:

http://localhost:8080/JSPBook/CH4/ErrorPage.jsp?num1=javaworld&num2=245

那么就会产生错误结果如图4-10。

当 ErrorPage.jsp 产生错误时,就会交由Error.jsp 去处理,所以您看到的结果,其实是执行

Error.jsp 后的结果。

图 4-10 ErrorPage.jsp 执行时产生错误

5-1 属性( Attribute )与范围( Scope )

有些JSP 程序员会将request、session、application 和pageContext 归为一类,原因在于:

它们皆能借助setAttribute( )和getAttribute( )来设定和取得其属性(Attribute),通过这两种

方法来做到数据分享

我们先来看下面这段小程序:

Page1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Page1.jsp</title>

</head>

<body>

</br>

<%

application.setAttribute("Name","mike");

application.setAttribute("Password","browser");

%>

<jsp:forward page="Page2.jsp"/>

</body>

</html>

在这个程序中,笔者设定两个属性:Name、Password,其值为:mike、browser。然后再转交(forward)

到Page2.jsp。我只要在Page2.jsp 当中加入application.getAttribute( ),就能取得在Page1.jsp

设定的数据。

Page2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Page2.jsp</title>

</head>

<body>

<%

String Name = (String) application.getAttribute("Name");

String Password = (String) application.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

Page1.jsp 的执行结果如图5-1 所示。

图 5-1 Page1.jsp 的执行结果

从图5-1 可以看出,此时Name的值就会等于mike,Password 的值就等于browser。看完这个小

范例之后,读者有没有发现网页之间要传递数据时,除了可以使用窗体、隐藏字段来完成之外,JSP

技术还提供给开发人员一项传递数据的机制,那就是利用setAttribute( )和getAttribute( )方法,

如同Page1.jsp 和Page2.jsp 的做法。不过它还是有些限制的,这就留到下一节来说明。

在上面 Page1.jsp 和Page2.jsp 的程序当中,是将数据存入到application 对象之中。除了

application 之外,还有request、pageContext 和session,也都可以设定和取得属性值,那它们

之间有什么分别吗?

它们之间最大的差别在于范围(Scope)不一样,这个概念有点像C、C++中的全局变量和局部变量

的概念。接下来就介绍JSP 的范围。

5-1-1 JSP ScopePage

JSP 有四种范围,分别为Page、Request、Session、Application。所谓的Page,指的是单单一

页JSP Page 的范围。若要将数据存入Page 范围时,可以用pageContext 对象的setAttribute( )

方法;若要取得Page范围的数据时,可以使用pageContext对象的getAttribute( )方法。我们将

之前的范例做小幅度的修改,将application 改为pageContext。

PageScope1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageScope1.jsp</title>

</head>

<body>

<h2>Page 范围 - pageContext</h2>

<%

pageContext.setAttribute("Name","mike");

pageContext.setAttribute("Password","browser");

%>

<jsp:forward page="PageScope2.jsp"/>

</body>

</html>

PageScope2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageScope2.jsp</title>

</head>

<body>

<h2>Page 范围 - pageContext</h2>

</br>

<%

String Name = (String)pageContext.getAttribute("Name");

String Password = (String)pageContext.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

执行结果如图5-2 所示。

图 5-2 PageScope1.jsp 的执行结果

这个范例程序和之前有点类似,只是之前的程序是application,现在改为pageContext,但是结

果却大不相同,PageScope2.jsp 根本无法取得PageScope1.jsp 设定的Name 和Password 值,因为在

PageScope1.jsp 当中,是把Name 和Password 的属性范围设为Page,所以Name 和Password 的值只能

在PageScope1.jsp当中取得。若修改PageScope1.jsp的程序,重新命名为PageScope3.jsp,如下:

PageScope3.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageScope3.jsp</title>

</head>

<body>

<h2>Page 范围 - pageContext</h2>

</br>

<%

pageContext.setAttribute("Name","mike");

pageContext.setAttribute("Password","browser");

String Name = (String)pageContext.getAttribute("Name");

String Password = (String)pageContext.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

PageScope3.jsp 的执行结果如图5-3 所示。

图 5-3 PageScope3.jsp 的执行结果

经过修改后的程序,Name 和Password 的值就能顺利显示出来。这个范例主要用来说明一个概

念:若数据设为Page范围时,数据只能在同一个JSP网页上取得,其他JSP网页却无法取得该数据。

5-1-2 JSP ScopeRequest

接下来介绍第二种范围:Request。Request 的范围是指在一JSP 网页发出请求到另一个JSP 网

页之间,随后这个属性就失效。设定Request 的范围时可利用request 对象中的setAttribute( )

和getAttribute( )。我们再来看下列这个范例:

RequestScope1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - RequestScope1.jsp</title>

</head>

<body>

<h2>Request 范围 - request</h2>

<%

request.setAttribute("Name","mike");

request.setAttribute("Password","browser");

%>

<jsp:forward page="RequestScope2.jsp"/>

</body>

</html>

RequestScope2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - RequestScope2.jsp</title>

</head>

<body>

<h2>Request 范围 - request</h2>

<%

String Name = (String) request.getAttribute("Name");

String Password = (String) request.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

RequestScope1.jsp 的执行结果如图5-4 所示。

现在将Name和Password的属性范围设为Request,当RequestScope1.jsp转向到RequestScope2.jsp

时,RequestScope2.jsp也能取得RequestScope1.jsp设定的Name和Password值。不过其他的JSP网页

无法得到Name和Password值,除非它们也和RequestScope1.jsp有请求的关系。

图 5-4 RequestScope1.jsp 的执行结果

除了利用转向(forward)的方法可以存取request 对象的数据之外,还能使用包含(include)的

方法。

假若我将RequestScope1.jsp 的

<jsp:forward page="RequestScope2.jsp"/>

改为

<jsp:include page="RequestScope2.jsp" flush="true"/>

执行RequestScope1.jsp 时,结果还是和图5-4 一样。表示使用<jsp:include>标签所包含进来

的网页,同样也可以取得Request 范围的数据。

5-1-3 JSP ScopeSessionApplication

表5-2 介绍了最后两种范围:Session、Application

表 5-2

范围 说 明

Session

Session 的作用范围为一段用户持续和服务器所连接的时间,但与服务

器断线后,这个属性就无效。只要将数据存入session 对象,数据的范

围就为Session

Application

Application 的作用范围在服务器一开始执行服务,到服务器关闭为

止。Application的范围最大、停留的时间也最久,所以使用时要特别注

意,不然可能会造成服务器负载越来越重的情况。只要将数据存入

application对象,数据的Scope 就为Application

表5-3 列出了一般储存和取得属性的方法,以下pageContext、request、session和application

皆可使用。

注意

pageContext 并无getAttributeNames( )方法。

表 5-3

方法 说 明

void setAttribute(String name, Object value) 设定name属性的值为value

Enumeration getAttributeNamesInScope(int

scope )

取得所有scope 范围的属性

Object getAttribute(String name) 取得name 属性的值

void removeAttribute(String name) 移除name 属性的值

当 我们使用getAttribute(String name)取得name 属性的值时,它会回传一个

java.lang.Object,因此,我们还必须根据name 属性值的类型做转换类型(Casting)的工作。例如:

若要取得String 类型的Name 属性时:

String Name = (String)pageContext.getAttribute("Name");

若是Integer 类型的Year 属性时:

Integer Year = (Integer)session.getAttribute("Year");

到目前已大约介绍完JSP 中四种范围(Scope):Page、Request、Session 和Application。假若

我的数据要设为Page 范围时,则只需要:

pageContext.setAttribute("Year", new Integer(2001));

若要为Request、Session 或Application 时,就分别存入request、session 或application

对象之中,如下:

request.setAttribute("Month", new Integer(12) );

session.setAttribute("Day", new Integer(27) );

application.setAttribute("Times", new Integer(10));

接下来就正式进入本章的主题:隐含对象(Implicit Object)。

5-2 与Servlet 有关的隐含对象

与 Servlet 有关的隐含对象有两个:page 和config。page 对象表示Servlet 本身;config 对

象则是存放Servlet 的初始参数值。

page 对象

page对象代表JSP本身,更准确地说,它代表JSP被转译后的Servlet,因此,它可以调用Servlet

类所定义的方法,不过实际上,page 对象很少在JSP 中使用。我们来看看以下的范例程序:

PageInfo.jsp

<%@ page info="JSP 2.0 技术手册" contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageInfo.jsp</title>

</head>

<body>

<h2>page 隐含对象</h2>

Page Info = <%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %>

</body>

</html>

这个例子中,我们先设定page 指令的info 属性为“JSP 2.0 技术手册”,page 对象的类型为

java.lang.Object,我们调用javax.servlet.jsp.HttpJspPage 中getServletInfo( )的方法,将

Info 打印出来,执行结果如图5-5 所示。

图 5-5 PathInfo.jsp 的执行结果

config 对象

config 对象里存放着一些Servlet 初始的数据结构,config 对象和page 对象一样都很少被用

到。config 对象实现于javax.servlet.ServletConfig 接口,它共有下列四种方法:

public String getInitParameter(name)

public java.util.Enumeration getInitParameterNames( )

public ServletContext getServletContext( )

public Sring getServletName( )

上述前两种方法可以让config对象取得Servlet 初始参数值,如果此数值不存在,就传回null。

例如:当我们在web.xml 中设定如下时:

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

version="2.4">

<servlet>

<servlet-name>ServletConfigurator</servlet-name>

<servlet-class>

org.logicalcobwebs.proxool.configuration.ServletConfigurator

</servlet-class>

<init-param>

<param-name>propertyFile</param-name>

<param-value>

WEB-INF/classes/Proxool.properties

</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

</web-app>

那么我们就可以直接使用config.getInitParameter("propertyFile")来取得名称为

propertyFile、其值为WEB-INF/classes/Proxool.properties 的参数。如下范例:

String propertyFile = (String)config.getInitParameter("propertyFile");

5-3 与 Input / Output 有关的隐含对象

本节中,我们将介绍和Input/Output 有关的隐含对象,它们包括:out、request 和response

对象。request 对象表示客户端请求的内容;response 对象表示响应客户端的结果;而out 对象负

责把数据的结果显示到客户端的浏览器。

request 对象

request 对象包含所有请求的信息,如:请求的来源、标头、cookies和请求相关的参数值等等。

在JSP 网页中,request 对象是实现javax.servlet.http.HttpServletRequest 接口的,

HttpServletRequest 接口所提供的方法,可以将它分为四大类:

(1) 在5-1-3 小节提到的储存和取得属性方法;

(2) 能够取得请求参数的方法,如表5-4:

表 5-4 取得请求参数的方法

方 法 说 明

String getParameter(String name) 取得name 的参数值

Enumeration getParameterNames( ) 取得所有的参数名称

String [] getParameterValues(String name) 取得所有name 的参数值

Map getParameterMap( ) 取得一个要求参数的Map

(3) 能够取得请求HTTP 标头的方法,如表5-5:

表 5-5 取得请求标头的方法

方 法 说 明

String getHeader(String name) 取得name 的标头

Enumeration getHeaderNames() 取得所有的标头名称

Enumeration getHeaders(String name) 取得所有name 的标头

int getIntHeader(String name) 取得整数类型name 的标头

long getDateHeader(String name) 取得日期类型name 的标头

Cookie [] getCookies( ) 取得与请求有关的cookies

(4) 其他的方法,例如:取得请求的URL、IP 和session,如表5-6:

表 5-6 其他请求的方法

方 法 说 明

String getContextPath( ) 取得Context 路径(即站台名称)

String getMethod( ) 取得HTTP 的方法(GET、POST)

String getProtocol( ) 取得使用的协议(HTTP/1.1、HTTP/1.0 )

String getQueryString( )

取得请求的参数字符串,不过,HTTP的方

法必须为GET

String getRequestedSessionId( ) 取得用户端的Session ID

String getRequestURI( )

取得请求的URL,但是不包括请求的参数

字符串

String getRemoteAddr( ) 取得用户的IP 地址

String getRemoteHost( ) 取得用户的主机名称

int getRemotePort( ) 取得用户的主机端口

String getRemoteUser( ) 取得用户的名称

void etCharacterEncoding(String

encoding)

设定编码格式,用来解决窗体传递中文的

问题

我们来看下面这个程序范例,相信对读者会更加有帮助。

Request.html

<html>

<head>

<title>CH5 - Request.html</title>

<meta http-equiv="Content-Type" content="text/html; charset=GB2312">

</head>

<body>

<form action="Request.jsp" method="GET">

Name:<input type="text" name="Name" size="20" maxlength="20"><br>

Number:<input type="text" name="Number" size="20" maxlength="20"><br><br>

<input type="submit" value="传送">

</form>

</body>

</html>

Request.html的执行结果如图5-6 所示,笔者在Name 的字段中输入browser;Number字段中输

入123456789。

图 5-6 Request.html 的执行结果

Request.jsp

<%@ page language="java" contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Request.jsp</title>

</head>

<body>

<h2>javax.servlet.http.HttpServletRequest 接口所提供的方法</h2>

getParameter("Name"):<%= request.getParameter("Name") %><br>

getParameter("Number"):<%= request.getParameter("Number") %><br>

getAttribute("Name"):<%= request.getAttribute("Name") %><br>

getAttribute("Number"):<%= request.getAttribute("Number") %><br><br>

getAuthType( ):<%= request.getAuthType() %><br>

getProtocol( ):<%= request.getProtocol() %><br>

getMethod( ):<%= request.getMethod() %><br>

getScheme( ):<%= request.getScheme() %><br>

getContentType( ):<%= request.getContentType() %><br>

getContentLength( ):<%= request.getContentLength() %><br>

getCharacterEncoding( ):<%= request.getCharacterEncoding() %><br>

getRequestedSessionId( ):<%= request.getRequestedSessionId() %><br><br>

getContextPath( ):<%= request.getContextPath() %><br>

getServletPath( ):<%= request.getServletPath() %><br>

getPathInfo( ):<%= request.getPathInfo() %><br>

getRequestURI( ):<%= request.getRequestURI() %><br>

getQueryString( ):<%= request.getQueryString() %><br><br>

getRemoteAddr( ):<%= request.getRemoteAddr() %><br>

getRemoteHost( ):<%= request.getRemoteHost() %><br>

getRemoteUser( ):<%= request.getRemoteUser() %><br>

getRemotePort( ):<%= request.getRemotePort() %><br>

getServerName( ):<%= request.getServerName() %><br>

getServerPort( ):<%= request.getServerPort() %><br>

</body>

</html>

Request.jsp 的执行结果如图5-7 所示。

图 5-7 Request.jsp 的执行结果

在Request.jsp中,使用request.getParameter("Name")和request.getParameter("Number"),

能够取得Request.html窗体的值。除了取得请求的参数值之外,也能取得一些相关信息,如:使用的

协议、方法、URI 等等。

response 对象

response 对象主要将JSP 处理数据后的结果传回到客户端。response 对象是实现

javax.servlet.http.HttpServletResponse 接口。表5-7、表5-8、表5-9列出了response对象的

方法。

表 5-7 设定表头的方法

方 法 说 明

void addCookie(Cookie cookie) 新增cookie

void addDateHeader(String name, long

date)

新增long类型的值到name标头

void addHeader(String name, String value)

新增String 类型的值到name 标

void addIntHeader(String name, int value)新增int 类型的值到name 标头

void setDateHeader(String name, long

date)

指定long类型的值到name标头

void setHeader(String name, String value)

指定String 类型的值到name 标

void setIntHeader(String name, int value)指定int 类型的值到name 标头

表 5-8 设定响应状态码的方法

方 法 说 明

void sendError(int sc) 传送状态码(status code)

void sendError(int sc, String

msg)

传送状态码和错误信息

void setStatus(int sc) 设定状态码

表 5-9 用来URL 重写(rewriting)的方法

方 法 说 明

String encodeRedirectURL(String

url)

对使用sendRedirect( )方法的URL 予以

编码

有时候,当我们修改程序后,产生的结果却是之前的数据,执行浏览器上的刷新,才能看到更

改数据后的结果,针对这个问题,有时是因为浏览器会将之前浏览过的数据存放在浏览器的cache

中,所以当我们再次执行时,浏览器会直接从cache 中取出,因此,会显示之前旧的数据。笔者将

写一个Non-cache.jsp 程序来解决这个问题。

Non-cache.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Non-cache.jsp</title>

</head>

<body>

<h2>解决浏览器 cache 的问题 - response</h2>

<%

if (request.getProtocol().compareTo("HTTP/1.0") == 0)

response.setHeader("Pragma", "no-cache");

else if (request.getProtocol().compareTo("HTTP/1.1") == 0)

response.setHeader("Cache-Control", "no-cache");

response.setDateHeader("Expires", 0);

%>

</body>

</html>

先用request 对象取得协议,如果为HTTP/1.0,就设定标头,内容为setHeader ("Pragma",

"no-cache");若为HTTP/1.1,就设定标头为response.setHeader ("Cache-Control", "no-cache"),

最后再设定response.setDateHeader("Expires", 0)。这样Non-cache.jsp 网页在浏览过后,就不

会再存放到浏览器或是proxy 服务器的cache 中。表5-10 列出了HTTP/1.1 Cache-Control 标头的

设定参数:

表 5-10 HTTP/1.1 Cache-Control 标头的设定参数

参 数 说 明

public

数据内容皆被储存起来,就连有密码保护的网页也是一样,

因此安全性相当低

private

数据内容只能被储存到私有的caches,即non-shared caches

no-cache

数据内容绝不被储存起来。proxy 服务器和浏览器读到此标

头,就不会将数据内容存入caches 中

no-store

数据内容除了不能存入caches中之外,亦不能存入暂时的磁

盘中,这个标头防止敏感性的数据被复制

must-revalidate

用户在每次读取数据时,会再次和原来的服务器确定是否为

最新数据,而不再通过中间的proxy 服务器

proxy-revalidate

这个参数有点像must-revalidate,不过中间接收的proxy

服务器可以互相分享caches

max-age=xxx

数据内容在经过xxx秒后,就会失效,这个标头就像Expires

标头的功能一样,不过max-age=xxx只能服务HTTP/1.1 的用

户。假设两者并用时,max-age=xxx 有较高的优先权

有时候,我们想要让网页自己能自动更新,因此,须使用到Refresh 这个标头。举个例子,我

们告诉浏览器,每隔三分钟,就重新加载此网页:

response.setIntHeader("Refresh" , 180)

如果想要过十秒后,调用浏览器转到http://Server/Path 的网页时,可用如下代码:

response.setHeader("Refresh","10; URL=http://Server/Path" )

如果大家对HTML 语法还熟悉,则HTML 语法中也有类似的功能:

<META HTTP-EQUIV="Refresh" CONTENT=" 10; URL=http://Server/Path" >

上述两种方法皆可以做到自动重新加载。

out 对象

out 对象能把结果输出到网页上。通常我们最常使用out.println(String name)和out.print(String

name),它们两者最大的差别在于println( )在输出的数据后面会自动加上换行的符号,例如:你在

Dos Console的窗口下,发现到它输出数据后会自动换行;反之,print( )不会在数据后自动换行。

out 对象除了这两种方法最常使用之外,它还有一些方法(见表5-11),这些方法主要是用来控

制管理输出的缓冲区(buffer)和输出流(output stream)。

表 5-11 out 对象方法

方 法 说 明

void clear( ) 清除输出缓冲区的内容

void clearBuffer( ) 清除输出缓冲区的内容

void close( ) 关闭输出流,清除所有的内容

int getBufferSize( ) 取得目前缓冲区的大小(KB)

int getRemaining( ) 取得目前使用后还剩下的缓冲区大小(KB)

boolean isAutoFlush( )

如果回传为true,表示如缓冲区满了,会自动清除;

若为false,表示如果缓冲区满了,不会自动清除,

而会产生异常处理

我们在这里举个例子,说明如何知道目前输出缓冲区的大小。

Out.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Out.jsp</title>

</head>

<body>

<h2>javax.servlet.jsp.JspWriter - out 对象</h2>

<%

int BufferSize = out.getBufferSize();

int Available = out.getRemaining();

int Used = BufferSize - Available;

%>

BufferSize : <%= BufferSize %><br>

Available : <%= Available %><br>

Used : <%= Used %><br>

</body>

</html>

BufferSize是一开始默认缓冲区的大小,默认值为8KB;Available 则是表示经过程序的执行,

目前缓冲区还剩下多少可以使用;而Used 则表示我们使用了多少的缓冲区。Out.jsp 执行结果如图