从例12-2中可以看到,在JSP容器生成的Servlet类的_jspService()方法中,定义了几个对象,而这些对象就是我们在编写JSP页面时,可以使用的隐含对象。要注意的是,因为这些隐含对象是在_jspService()方法中定义的,所以我们只能在脚本段和表达式中使用这些对象。
在JSP页面中,总共有9个隐含对象:request,response,pageContext,session,application,out,config,page和exception。在基于HTTP协议的实现中,这9个隐含对象与它们各自的类型如表12-3所示。
表12-3 JSP隐含对象的类型
隐含对象 | 类 型 |
request | javax.servlet.http.HttpServletRequest |
response | javax.servlet.http.HttpServletResponse |
pageContext | javax.servlet.jsp.PageContext |
session | javax.servlet.http.HttpSession |
application | javax.servlet.ServletContext |
out | javax.servlet.jsp.JspWriter |
config | javax.servlet.ServletConfig |
page | java.lang.Object |
exception | java.lang.Throwable |
其中request,response,session,application和config对象所属的类及其用法在前面的Servlet章节中我们已经介绍过了,下面主要介绍一下其他的对象。
12.4.1 pageContext
pageContext对象提供了访问其他隐含对象的方法,如下:
? public abstract javax.servlet.ServletRequest getRequest()
? public abstract javax.servlet.ServletResponse getResponse()
? public abstract javax.servlet.http.HttpSession getSession()
? public abstract javax.servlet.ServletContext getServletContext()
? public abstract JspWriter getOut()
? public abstract javax.servlet.ServletConfig getServletConfig()
? public abstract java.lang.Object getPage()
? public abstract java.lang.Exception getException()
在pageContext对象中,可以使用下面两个方法来保存和获取属性。
? public abstract void setAttribute(java.lang.String name, java.lang.Object value)
? public abstract java.lang.Object getAttribute(java.lang.String name)
在pageContext对象中保存的属性,只能在当前页面中去获取,也就是说,pageContext对象具有页面范围(详见12.5节)。
利用pageContext对象,还可以设置和得到在其他范围对象中保存的属性。pageContext对象提供了另外两个setAttribute()和getAttribute()方法,如下:
? public abstract void setAttribute(java.lang.String name, java.lang.Object value, int scope)
? public abstract java.lang.Object getAttribute(java.lang.String name, int scope)
其中的scope参数用于指定要获取哪一个范围对象的属性,有四个可能的取值,其中PageContext. PAGE_SCOPE表示页面范围,PageContext.REQUEST_SCOPE表示请求范围,PageContext.SESSION_ SCOPE表示会话范围,PageContext.APPLICATION_SCOPE表示Web应用程序范围。
在pageContext对象中,可以使用下面两个方法来删除范围中的属性。
? public abstract void removeAttribute(java.lang.String name, int scope)
删除指定范围内名字为name的属性。
? public abstract void removeAttribute(java.lang.String name)
删除所有范围内名字为name的属性。
pageContext对象还提供了搜索属性的方法:
? public abstract java.lang.Object findAttribute(java.lang.String name)
该方法会按照page,request,session和application范围的顺序搜索指定名字的属性,如果找到,则返回属性的值,如果没有找到,则返回null。关于范围,请参见12.5节。
pageContext对象也提供了请求转发的两个方法forward()和include(),其内部实现是调用RequestDispatcher对象的forward()和include()方法。
从pageContext对象提供的方法可以看出,pageContext对象实际上是为我们提供了访问其他隐含对象的统一入口,在多数情况下,直接利用pageContext对象就可以完成想要实现的功能。
12.4.2 out
out对象的类型是javax.servlet.jsp.JspWriter,该类从java.io.Writer类派生,以字符流的形式输出数据。out对象实际上是PrintWriter对象的带缓冲的版本(在out对象内部使用PrintWriter对象来输出数据),可以通过page指令的buffer属性来调整缓冲区的大小,默认的缓冲区是8kb。
在out对象中,提供了几个和缓冲区操作相关的方法,如下所示。
? public abstract void clear() throws java.io.IOException
清除缓冲区中的内容。如果缓冲区已经被刷新,clear()方法将抛出IOException异常。
? public abstract void clearBuffer() throws java.io.IOException
清除缓冲区中的当前内容。这个方法和clear()方法的区别是,如果缓冲区已经被刷新,这个方法不会抛出IOException异常。
? public abstract void close() throws java.io.IOException
刷新缓冲区,关闭输出流。注意,我们在编写JSP页面时,不需要显式地去调用这个方法,因为在JSP容器所生成的代码中会自动包含对close()方法的调用。
? public abstract void flush() throws java.io.IOException
刷新缓冲区。
? public int getBufferSize()
获得out对象使用的缓冲区的大小。
? public abstract int getRemaining()
获得缓冲区中未使用的字节数。
? public boolean isAutoFlush()
判断out对象是否是自动刷新。
out对象针对不同的数据类型,提供了多个重载的print()和println()方法,用于输出数据。要注意的是,虽然println()方法会输出一个换行,但是客户端的浏览器在显示页面时会忽略输出的换行。
12.4.3 page
page对象是当前页面转换后的Servlet类的实例。从转换后的Servlet类的代码中,可以看到这种关系:
Object page = this;
在JSP页面中,很少使用page对象。
12.4.4 exception
exception对象表示了JSP页面运行时产生的异常,该对象只有在错误页面(在page指令中指定属性isErrorPage=true的页面)中才可以使用。
在JSP页面中,我们可以利用page指令的errorPage属性指定一个错误处理页面,当JSP页面运行发生错误时,JSP容器会自动调用指定的错误处理页面。要注意的是,如果一个JSP页面使用errorPage属性定义了错误页面,那么在web.xml文件中定义的任何错误页面将不会被使用。
下面我们看一个例子:
price.jsp
<%@ page errorPage="excep.jsp" %>
<%
String strPrice=request.getParameter("price");
double price=Double.parseDouble(strPrice);
out.println("Total price = "+price * 3);
%>
excep.jsp
<%@page isErrorPage="true" %>
<%
out.println("exception.toString():");
out.println("<br>");
out.println(exception.toString());
out.println("<p>");
out.println("exception.getMessage():");
out.println("<br>");
out.println(exception.getMessage());
%>
在price.jsp页面中,通过page指令的errorPage属性指定错误处理页面为excep.jsp。在excep.jsp页面中,通过page指令的isErrorPage属性指定当前页面是错误处理页面,只有设置了isErrorPage为true,在此页面中才可以使用exception对象。
我们访问price.jsp页面时,输入URL:http://localhost:8080/ch12/price.jsp?price=5.0
将看到输出:
Total price = 15.0
如果输入:http://localhost:8080/ch12/price.jsp?price=abc
将看到如下的错误信息:
exception.toString():
java.lang.NumberFormatException: For input string: "abc"
exception.getMessage():
For input string: "abc"