JSP 脚本中包含 9 个内置对象,这 9 个内置对象都是 Servlet API 接口的实例,只是 JSP 规范对它们进行了默认的初始化(由 JSP 页面对应的 Servlet 的 _jspService() 方法来创建这些实例),即它们已经是对象了,可以直接使用。
9 个内置对象依次如下:
打开 Tomcat\work\cataline\localhost\…\jsp,其中几乎所有的 JSP 页面编译后 Servlet 类都有如下所示结构:
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, false, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
out = pageContext.getOut();
_jspx_out = out;
// ...
}
}
}
说明:
注意:
由于 JSP 内置对象都是在 _jspService() 方法中完成初始化的,因此在 JSP 脚本、JSP 输出表达式中使用这些内置对象,不能在 JSP 声明中使用它们,否则,系统将提示找不到这些变量。
application 对象代表 Web 应用本身,因此使用 application 来操作 Web 应用相关数据。application 对象通常有如下两个作用:
application 通过 setAttribute(String attrName, Object value) 方法将一个值设置成 application 的 attrName 属性,该属性的值对整个 Web 应用有效,因此该 Web 应用的每个 JSP 页面或 Servlet 都可以访问该属性,访问该属性的方法为 getAttribute(String attrName)。
在 JSP 中可直接通过 application 内置对象在 JSP 脚本或者表达式中进行赋值和取值:
<%
application.setAttribute("name", "JSP")
%>
<%=application.getAttribute("name")%>
在 Servlet 中,必须先获取 ServletContext 对象,才能进行赋值和取值:
ServletContext sc = getServletContext();
// ServletContext sc = getServletConfig().getServletContext();
sc.setAttribute("name", "Servlet");
sc.getAttribute("name");
建议:
虽然使用 application(即 ServletContext 实例)可以方便多个 JSP、Servlet 共享数据,但不要仅为了 JSP、Servlet 共享数据就将数据放入 application 中。由于 application 代表整个 Web 应用,所以通常只应该把 Web 应用的状态数据放入 application 里。
因为 application 对象代表 Web 应用本身,所以可用于获取 Web 应用的初始化配置参数。
在 JSP 页面中的访问方式如下:
<% String name = application.getInitParameter("name"); %>
在 web.xml 文件的根元素(web-app)下配置 Web 应用的初始化参数:
<web-app ...>
......
<context-param>
<param-name>name</param-name>
<param-value>web</param-value>
</context-param>
</web-app>
config 对象代表当前 JSP 配置信息,但 JSP 页面通常无须配置,也就不存在配置信息。此对象在 JSP 页面中比较少用,此处简单作说明,但在 Servlet 中则用处相对较大,详见 Servlet。
在 JSP 获取配置参数:
<%=config.getServletName()%>
<%=config.getInitParameter("name")%>
在 web.xml 中为 JSP 配置初始化参数:
<servlet>
<servlet-name>config</servlet-name>
<jsp-file>/config.jsp</jsp-file>
<init-param>
<param-name>name</param-name>
<param-value>jsp config</param-value>
</init-param>
</servlet>
注意:
由于对 JSP 进行了如上配置(相当于将 JSP 作为 Servlet 进行配置),所以,此 JSP 页面存在两种访问方式:
不过要想在 JSP 页面中通过 config 内置对象获取在 web.xml 中配置的初始化参数,必须使用第二种方式。
exception 对象是 Throwable 的实例,代表 JSP 脚本中产生的错误和异常,是 JSP 页面异常机制的一部分。
在 JSP 脚本中无须处理异常,即使该异常是 checked 异常。事实上,JSP 脚本包含的所有可能出现的异常都可交给错误处理页面处理。
打开普通的 JSP 页面生成的 Servlet 类如下:
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
// 内置对象定义,init(),destory()...
try {
// 内置对象初始化,所有 JSP 脚本、静态 HTML 部分都会转换成此部分代码
} catch (java.lang.Throwable t) { // 异常处理
if (!(t instanceof javax.servlet.jsp.SkipPageException)) {
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally { // 释放资源
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
说明:
在 JSP 的异常处理机制中,一个异常处理页面可以处理多个 JSP 页面脚本部分的异常,异常处理页面通过 page 指令的 errorPage 属性确定。在异常处理页面中,需要通过 page 指令中指定 isErrorPage 属性为 true,否则 JSP 的异常处理机制无法找到 errorPage 属性指定的异常处理页面,该页面中也无法访问 exception 内置对象。
在 JSP 的异常处理页面,可以使用如下方法获取异常信息:
异常类型:<%=exception.getClass()%>
异常信息:<%=exception.getMessage()%>
out 对象代表一个页面输出流,通常用于在页面上输出变量值及常量。一般在使用输出表达式的地方,都可以使用 out 对象来达到同样的效果,<%=...%>
的本质就是 out.write(…)。建议使用输出表达式,更加简洁。
在 JSP 页面中使用 out 对象的语法如下:
<%
out.write("abc");
%>
这个对象代表页面上下文,该对象主要用于访问 JSP 之间的共享数据。使用 pageContext 对象可以访问 page、request、session 和 application 范围的变量。
pageContext 是 PageContext 实例,它提供了如下两个方法来访问 page、request、session 和 application 范围的变量:
getAttribute(String name, int scope):取得指定范围内的 name 属性,其中 scope 可以是如下 4 个常量值:
与 getAttribute() 方法相对应,PageContext 也提供了 2 个对应的 setAttribute() 方法,用于将指定变量的值存入指定的范围内:
在 JSP 页面中使用 pageContext 对象进行相关范围内的赋值与取值语法:
<%
pageContext.setAttribute("username", "administrator", PageContext.SESSION_SCOPE);
pageContext.getAttribute("username", PageContext.SESSION_SCOPE);
%>
pageContext 还可获取其他内置对象,方法如下:
因此一旦在 JSP、Servlet 编程中获取了 pageContext 对象,就可以通过它获取其他内置对象。
每个 request 对象封装着一次用户请求,并且所有的请求参数都被封装在 request 对象中。该对象通常有如下几个作用:
request 是 HttpServletRequest 接口的实例,它提供了如下几个方法来获取请求参数:
HttpServletRequest 提供了如下方法来访问请求头:
HttpServletRequest包含如下两个方法,用于设置和获取 request 范围的属性:
除了 JSP 提供的 forward 和 include 动作指令,request 也可以执行 forward 和 include。
HttpServletRequest 类提供了一个 getRequestDispatcher(String path) 方法,其中 path 就是希望 forward 或者 include 的目标路径,该方法返回 RequestDispatcher,该对象提供了如下两个方法:
response 对象代表服务器对客户端的响应。通常情况下,在 JSP 页面中直接使用 out 对象来输出响应信息即可,但 out 是 Writer 的子类,是一个字符输出流,对于非字符内容,就必须使用 response 作为输出响应。除此之外,还可以使用 response 来重定向请求以及用于向客户端增加 Cookie。
response 是 HttpServletResponse 接口的实例,该接口提供了一个 getOutputStream() 方法,该方法返回响应的输出字节流。
HttpServletResponse 提供了一个 sendRedirect(String path) 方法,该方法用于重定向到 path 资源,即重新向 path 资源发送请求。
Cookie 通常用于网站记录客户的某些信息,存放客户端机器上,直到超出 Cookie 的生命期限。客户端浏览器完全可以禁用 Cookie,所以使用 Cookie 必须客户端浏览器支持才行。
response 对象提供如下方法增加 Cookie:
session 对象代表一次用户会话。一次用户会话是从客户端浏览器连接服务器开始,到客户端浏览器与服务器断开为止。session 范围内的属性可以在多个页面的跳转之间共享,一旦关闭浏览器,即 session 结束,session 范围内的属性将全部丢失。
session 对象是 HttpSession 的实例,HttpSession 有如下两个常用的方法:
在 JSP 九大内置类中存在四大域对象,分别是:
域对象主要是用于 JSP 和 Servlet 的数据共享。