第
5 
章基本JSP 
程序设计

JavaServerPages(JSP)是基于Java语言的脚本技术,是JavaEEWeb 
层用于生成网页的另外一种主要技术。JSP 使用类似于HTML 的标记和
Java代码段,能够将HTML 代码从Web页面的业务逻辑中分离出来。
JSP 技术规范的目标是通过提供一种比Servlet更简洁的程序设计结构,以
简化动态Web页面的生成和管理。每个JSP 页面在第一次被调用时都会
被翻译成一个Servlet,而该Servlet是JSP 页面中的标记和脚本标记指定
的嵌入动态内容的结合体。本章首先介绍JSP 的基本运行原理、执行机制
和生命周期,然后在此基础上介绍JSP 页面的基本组成、语法、JSP 隐含对
象的用途和适用范围。最后,本章通过实例阐述了在OracleJDeveloper和
OC4J 环境下,开发、部署和运行JSP 的基本原理和方法。

5.SP 
概述
1J

JSP 是一种用于取代CGI 的技术,而且性能比CGI 脚本优越。Servlet 
在服务器上运行并且截获来自客户端浏览器的请求,适用于确定如何处理
客户请求以及调用其他的服务器对象。但是,Servlet并不适用于生成页面
内容。另外,从Java代码中生成标记是很难维护的,而且Servlet必须由熟
悉Java语言的开发者编写。Servlet与JSP 在功能上虽然有所重叠,但是
可以把Servlet看作控制对象,而把JSP 看作视图对象。在创建JavaWeb 
应用时,不需要在使用Servlet还是使用JSP 之间做出艰难的选择。
Servlet与JSP 是互补的技术,对复杂的Web应用,它们两者都会被使
用到。

另一方面,aaenaa标记对静态HTML 代码和动

JSP 利用JvBas和Jv
态数据进行了分离。静态HTML 代码由HTML 程序员负责编写,而动态
数据和JavaBeans由Java程序员负责编写。这样的分工原则,可以使不同
的程序员专注于各自的领域。


58
Java 
Web 
与JavaFX 
应用开发———基于Oracle 
JDeveloper、Oracle 
DB 
XE 
与NetBeans 
实现

5.1.1 
JSP 
运行原理
当客户使用浏览器上网时,服务器能够解释来自客户机的信息,这是因为客户机和服
务器都遵守了TCP/IP 族的标准。TCP/IP 通过Internet决定了信息的分发和路由。
HTTP 给出了Web页面请求和响应的格式,这些协议共同工作在网络的传输层上。浏
览器根据HTTP 定制的规则构造请求,然后浏览器通过另一个称为TCP/IP 堆栈的软件
处理请求。TCP/IP 堆栈初始化请求的分发和路由。当请求最终到达一台服务器时,它
的TCP/IP 堆栈将所有到达的请求组合在一起,并将请求传输给服务器软件(即OC4J 提
供的JSP 容器), 根据HTTP 规则解释这个请求。

服务器不仅运行JSP 容器,也运行一个TCP/IP 堆栈,还可以运行其他的软件。通
常,则

JSP 容器仅负责请求/响应周期的HTTP 部分。如果用户请求的是一个JSP 页面, 
服务器将这个请求转发给JSP 容器,

JSP 容器解释JSP 代码并构造一个HTML 文档传输

给浏览器。

服务器将请求转发给一个JSP 容器有许多方法,其中常用的一种方法是通过TCP/
IP 堆栈进行通信。通常服务器软件和JSP 容器并不驻留在同一台计算机上,它们通过一
个TCP/IP 堆栈共享信息。图5-1阐述了JSP 的运行原理。

提示:读者出于学习目的,可以在本地计算机上同时运行一个客户机浏览器、一个服
务器和一个JSP 容器(OC4J), 在运行时再对Web应用进行实际的部署。


图5-
1 
服务器与JSP 
容器通过TCP/IP 
堆栈进行通信

5.1.2 
JSP 
生命周期
JSP 生命周期包括jspInit()、jspService(), 以及jspDestroy()3个方法,这些方法是
根据JSP 的状态从JSP 容器中被调用的。
jasljspPgrl

avx.ervet.p包中定义了一个Jsae接口(继承自Sevet接口), 该接口定义了
jspInit() 与jspDestroy() 两个方法。无论客户端使用哪种通信协议,实现JspPage接口的


第
5 
章 基本JSP 
程序设计 

类都可以经由jspInit()与jspDestroy()方法完成初始化和资源释放动作。针对HTTP 
通信协议,jvx.eve.ssae接口。该接口只定义了一个

aasrltjp包定义了一个HtpJpPgjspService()方法。
一般地,把jspInit()、jspService(),以及jspDestroy()3个方法称为JSP生命周期

方法。
● 当一个JSP页面第一次请求时,JSP容器将把该JSP页面转换为一个Servlet。
JSP容器首先把该JSP页面转换成一个Java源文件,在转换时如果发现语法错
误,则将中断转换,并向服务器和客户机输出错误信息;如果转换成功,JSP容器将

avaavclas 

用jc把Ja源文件编译成.文件。上述过程执行完成之后,JSP容器将创
建一个Servlet实例,该Servlet的jspInit()方法将被执行。

●jspInit()方法在Servlet生命周期中只被执行一次,然后将调用jspService()方法
处理来自客户机的请求。对每一个请求,JSP容器将会创建一个新线程来处理这
个请求。如果有多个客户机同时请求这个JSP页面,则JSP容器将会创建多个线
程。每个客户机请求对应一个线程。以多线程方式执行JSP页面可大大降低对
系统的资源需求,提高系统的并发量及响应时间,但是应当注意多线程的编程
限制。
● 由于这个Servlet始终驻留在内存之中,所以响应速度非常快。如果JSP页面被修
改过,服务器将根据设置决定是否对其重新编译。如果需要重新编译,则将编译结
果取代内存中的Servlet,并继续进行上述过程。虽然JSP执行效率很高,但在第
一次调用时由于需要进行转换和编译,所以会稍有延迟。此外,如果出现系统资源
不足的情形,y()方法首先将被调用,然后St实例将被标记加入“垃
jspDestroervle
圾回收器”处理
。


5.1.3 
JSP 
执行过程
JSP页面的执行过程如图5-2所示。


图5-
2 
JSP页面的执行过程

●JSP页面及其相关文件总称为翻译单元(TranslationUnit)。JSP容器第一次为一
个JSP页面截获一个请求时,翻译单元将把它翻译成一个Servlet。这个编译过程

60 Java Web 与JavaFX 应用开发———基于Oracle JDeveloper、Oracle DB XE 与NetBeans 实现
包括两个阶段:第一个阶段是把JSP源代码转换成一个Servlet;第二个阶段包括
编译这个Servlet。
● JSP页面第一次由JSP容器装入时,实现JSP标记的Servlet代码会自动生成、编
译并加载到OC4J提供的Servlet容器中。这种情况发生在翻译时间,而且只在第
一次请求JSP页面时才发生,所以第一次访问JSP页面时响应速度会稍慢些。但
以后的请求直接由已经编译过的Servlet处理,这些过程发生在运行时间里。因
此,理解JSP页面执行过程的关键是正确区分翻译时间与运行时间。
5.2 JSP脚本元素
JSP页面包含HTML与JSP两类标记。HTML标记用一对尖括号括住,而JSP标
记则括在一对尖括号和一对百分号中。HTML是页面设计的基本语言,使用JSP标记的
文档会被JSP容器转换成HTML标记。JSP不仅可以使用本身固有的语法,也可以和
HTML标记一起使用。JSP页面可以是模板元素、注释、脚本元素、指令元素以及操作元
素这5种元素中的一种或组合体。
如果JSP页面中使用的编程语言位于JSP标记的外部,则JSP容器会将它识别为模
板数据(TemplateData),并直接将它显示在页面中。模板元素是指JSP的静态HTML 
或XML内容,它对JSP的显示是非常必要的。模板元素是网页的框架,它影响着页面的
结构和美观程度。在编译JSP页面时,JSP容器将把模板元素编译到Servlet中。当客户
请求该JSP页面时,JSP容器会把模板元素发送到客户端。一个带有Java代码的JSP标
记称为脚本元素,JSP页面中有声明、表达式和脚本3种类型的脚本元素。
1.声明
声明(Declaration)用于在JSP页面中定义方法和实例变量。声明并不生成任何将会
送给客户机的输出。其一般语法格式如下: 
< % !方法或实例变量的定义%> 
2.表达式
表达式(Expression)用于把动态内容(变量值或方法的运算结果)传递给客户端浏览
器界面。其一般语法格式如下。 
< %=变量或方法的值%> 
“变量或方法的值”可以是前面声明中定义的方法或实例变量中的任何一个返回值。
例如,下面的程序片段: 
<%! public double pi=3.14159; %> 
<%=pi %> →输出3.14159 
pi →输出pi 
从输出结果可以看出,pi只有在JSP表达式中才有效,而没有使用表达式的pi将被
原样显示在浏览器的界面上。在表达式中可以使用任何形式的变量,JSP容器会将标记

第5 章 基本JSP 程序设计  61 
中的值全部转换成字符串并输出到浏览器界面上。
3.脚本
脚本(Scripting)是用于解释Java语言的标记。如果在JSP页面中嵌入Java语句,则
JSP容器会解释脚本标记内的Java语句,并根据其语法在浏览器页面上运行。其一般语
法格式如下。 
<%Java 代码%> 
脚本标记中的Java代码大都用于完成运算功能,所以这些Java代码的运算结果无
法直接显示在浏览器页面中。与声明不同,脚本标记可以将一个完整的程序分开使用。
例如下面的程序片段: 
<%for(int i=0; i<3; i++) { %> 
这是脚本
<%} %> 
4.注释
所谓注释(Comments),是在程序代码中用于说明程序流程的语句。JSP页面中的注
释语句如表5-1所示。
表5-1 JSP页面的注释语句
种 类表示形式
HTML注释语句<!--注释--> 
JSP注释语句<%--注释语句--%> 
Script语言注释语句<%//注释语句%><%/*注释语句*/%> 
5.3 基于IDE开发JSP页面
基于JDeveloper开发JSP页面,可以充分利用IDE的可视化编辑器提供的HTML 
组件面板和JSP组件面板提供的标记,有效地提升开发效率。下面通过一个实例,介绍
开发JSP页面的可视化编辑器的使用方法。这个实例要求编写一个JSP页面,用于显示
1~6的平方根表。
(1)在JDeveloper 中创建ch05.jws,在该Application 中创建一个工程文件
sqrtTable.jpr。
(2)在工程文件sqrtTable中创建一个JSP程序。从主菜单中选择File→New命令, 
在显示的对话框的Categories区域中选择WebTier→JSP,在Item 区域中选择JSP,单击
“确定”按钮,则显示WelcometotheCreateJSP Wizard窗口。单击“下一步”按钮,显示
如图5-3所示的选择Web应用的版本对话框。
(3)单击“下一步”按钮,显示如图5-4 所示的对话框。在File Name 域输入
sqrtTable.jsp,在DirectoryName域使用它的默认值,Type选择JSPPage(*.jsp)。

62
Java 
Web 
与JavaFX 
应用开发———基于Oracle 
JDeveloper、Oracle 
DB 
XE 
与NetBeans 
实现


图5-
3 
选择Web应用的版本


图5-
4 
输入Web应用的名称、路径以及选择程序类型

(4)单击“下一步”按钮,显示选择“出错页面参数”对话框,如图5-5所示。
图5-
5 
选择“出错页面参数”对话框

(5)单击“下一步”按钮,显示“使用其他组件库”对话框,本例暂不使用。单击“下一

第5 章 基本JSP 程序设计  63 
步”按钮,显示如图5-6所示的对话框。可以选择HTML版本,输入JSP页面的标题,设
置JSP页面的背景颜色和样式表。
图5-6 选择HTML版本,输入JSP页面的标题等
(6)单击“完成”按钮,在CodeEditor生成JSP页面源代码。
(7)根据题目要求修改生成的JSP源代码,具体如下所示。 
1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
2. "http://www.w3.org/TR/html4/loose.dtd"> 
3. <%@ page contentType="text/html;charset=GB2312"%> 
4. <HTML><HEAD> 
5. <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=GB2312"> 
6. <TITLE>Table Of Square Roots</TITLE></HEAD> 
7. <BODY> 
8. <!--表标题--> 
9. <CENTER>平方根表</CENTER> 
10. <!--表头--> 
11. <TABLE CELLSPACING="2" CELLPADDING="1" BORDER="2" WIDTH="100%" ALIGN= 
"LEFT"> 
12. <TR> 
13. <TD>数字</TD> 
14. <TD>平方值</TD> 
15. </TR> 
16. <%--表体部分, 输出数的平方根--%> 
17. <%for(int n=1;n<=6;n++) { %> 
18. <TR> 
19. <%/*输出数*/ %><TD><%=n%></TD> 
20. <%/*输出数的平方根*/ %><TD><%=Math.sqrt(n) %></TD> 
21. </TR> 
22. <%} %>

64 Java Web 与JavaFX 应用开发———基于Oracle JDeveloper、Oracle DB XE 与NetBeans 实现
23. </TABLE></BODY> 
24. </HTML> 
(8)完成JSP页面的源代码编写工作之后,就可以将Web应用部署到OC4J容器。
图5-7所示为JSP页面的执行结果。
图5-7 JSP页面的执行结果
【分析讨论】
● 第3句表示指定输出文本为HTML,字符编码为GBK。
● 该JSP页面创建了一个HTML表,表的每一行都封装在<TR>和</TR>标记
中。由于使用了for循环,所以执行一次循环体,都要用一对新的<TR> 和
</TR>标记创建表的一个新行。
● 每一对标记中都有两个JSP表达式:一个用于输出数n;一个用于输出该数的平
方根。
5.4 JSP隐含对象
JSP可以使用ServletAPI提供的特定隐含对象。这些对象在JSP页面中可以使用
标准变量实现访问,并且不再需要开发人员重新声明,就可以在任何JSP表达式和脚本
中使用,这些对象称为隐含对象(ImplicitObjects)。利用这些隐含对象,可以在JSP页面
中直接存取Web应用的运行环境信息,如表5-2所示。例如,通过request对象可以取得
HTTP请求内容,通过application对象可以取得web.xml文件的配置信息等。
表5-2 JSP隐含对象及用途
JSP隐含对象用 途
request 客户机发送的HTTP请求
response 服务器要发送给客户端的HTTP响应
out 输出数据流的JspWrite对象
config JSP页面编译后产生的Servlet相关信息的ServletConfig对象

第 
5 
章 基本JSP 
程序设计 

续表

65
JSP隐含对象用途
pageContext JSP页面信息的pageContext对象
page 相当于Java语言的this对象
exception 其他JSP抛出的异常
sesion 用于存取HTTP会话内容
application Web应用配置信息的ServletContext对象

5.4.1 
对象使用范围
JSP对象、JavaBeans对象以及隐含对象的使用范围是一个非常重要的概念,因为它
定义了相关对象来自哪个JSP页面以及生存时间。对象的使用范围在内部依赖于上下
文环境(Context),一个Context为资源提供了一个不可见的容器与接口,供它们与程序
环境通信。例如,一个Servlet在一个上下文环境中运行,这个Servlet就需要知道关于服
务器的所有资源都可以从这个上下文环境中提取,并且服务器需要与这个Servlet通信的
所有信息通过这个上下文环境传递。JSP技术规范为开发人员使用的对象定义了4个范
围,如表5-3所示。

表5-
3 
对象的使用范围

维护使用说明
page 只能在引用特定对象的JSP页面中访问这些对象
request 可以在所有服务于当前请求的页面中访问这些对象,其中包括转发到或包含在原
始JSP页面中的页面。相应的请求被导入这些JSP页面
sesion 只能通过定义相关对象时访问的JSP页面访问这些对象
application 应用程序范围对象可以由一个给定上下文环境中的所有JSP页面访问

5.4.2 
request 
对象
HTTP描述了来自客户机的请求与服务器的响应两方面内容。在JSP页面中,可以
用request和response两个隐含对象表示这两方面的内容。

下面的Web应用实例,用于得到来自客户机请求的相关信息。该Web应用的实现
原理是:request对象是ServletRequest接口的一个针对协议和具体实现的子类,具有
request使用范围。而且request对象包含了客户机向服务器发出请求的内容,可以通过
该对象了解客户机向服务器发出请求的内容和客户端所要求的信息。

在ch05.ws中创建一个工程文件jpRqetjpr,在该工程中创建一个JSP页面文

jseus.
件jspRqetj.p和一个部署描述文件jsequs.eply。jpRqetjp的源代码如
下所示
e
。
usspRetdoseus.s


66 Java Web 与JavaFX 应用开发———基于Oracle JDeveloper、Oracle DB XE 与NetBeans 实现 
1. <%@ page contentType="text/html;charset=GB2312"%> 
2. <HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; 
charset=GB2312"> 
3. <TITLE>request/response 实例</TITLE></HEAD> 
4. <BODY> 
5. <B>Browser:</B><%=request.getHeader("User-Agent") %><BR> 
6. <B>Cookies:</B><%=request.getHeader("Cookie") %><BR> 
7. <B>Accepted MIME types:</B><%=request.getHeader("Accept") %><BR> 
8. <B>HTTP method:</B><%=request.getMethod() %><BR> 
9. <B>IP Address:</B><%=request.getRemoteAdd() %><BR> 
10. <B>DNS Name(or IP Address again):</B><%=request.getRemoteHost() %><BR> 
11. <B>Country:</B><%=request.getLocale().getDisplayCountry() %><BR> 
12. <B>Language:</B><%=request.getLocale().getDisplayLanguage() %><BR> 
13. </BODY></HTML> 
JSP页面的执行结果如图5-8所示。
图5-8 JSP页面的执行结果
【分析讨论】
● 一个HTTP请求可以有一个或多个标题,每个标题都有一个名字和一个值。为了
返回客户机请求的标题值,JSP页面调用了request对象的getHeader()方法。通
过JSP页面中的第5、6、7句可以得到以下3个值:User-Agent———包含一个描述
客户机浏览器的信息;Cookie标题———包含客户机前一次访问服务器时发送的信
息,标题值是一个标题号。Accept标题———包含浏览器响应请求时接收到的
MIME类型的列表。
● JSP页面中的第8句,通过调用request对象的getMethod()方法得到HTTP的请
求方法是get()。
● 第9句通过调用getRemoteAdd()方法返回产生请求的客户机IP地址。第10句
通过调用getRemoteHost()方法得到服务器的DNS。如果没有可用的DNS,则服
务器再次返回IP地址。