第3 章
Web 应用开发基础 
学习目标
理解开发环境与运行环境
掌握JavaWeb应用开发环境的搭建
理解JSP的运行机制和基础语法
掌握结构化网页开发的方法
3.1 开发环境和运行环境
在以往的程序设计学习中,读者可能使用过不同的开发工具,如学习C语言时使用
的VC++,学习Java语言时使用的IDEA 等。一般的开发过程是在开发工具中创建源程
序并编写代码,然后再使用开发工具所提供的编译功能将源程序编译为目标程序,最后使
用开发工具的运行功能来运行目标程序,得到需要的结果。因为通常会使用集成开发工
具,所开发的程序也大多运行在操作系统上,所以对开发程序和运行程序两种情况下的环
境需求不做明确地区分。但对于JavaWeb应用程序来说,开发环境和运行环境是两个不
同的概念,需要区分理解。
3.1.1 开发环境
开发环境是指程序员为了编写程序所需要的软件集合。利用这些软件,程序员可以
使用某种程序设计语言编写应用程序,实现各种功能。
完整的程序开发包括编码、编译、调试运行等阶段。最简单的开发环境是在不同的开
发阶段使用不同的工具软件。例如,先用文本编辑软件编写源程序,然后编译工具进行编
译,最后用运行工具进行调试运行。
对于Java程序开发,可以用任意的文本编辑软件编写.java源文件,然后使用javac 
把源文件编译成.class字节码文件,最后使用Java运行字节码文件;也可以使用集成开发
环境(IntegratedDevelopmentEnvironment,IDE)来进行程序开发。IDE中通常包含了
代码编辑器、程序编译器、调试器以及图形界面工具,将代码编写功能、编译功能、调试功
能、运行功能等集成为一体。常用的Java 集成开发工具有IntelliJIDEA、Eclipse、
JBuilder以及微软公司的VisualStudio等。
集成开发工具可以有效地提高开发效率,简化开发过程,在实际项目开发中一般都会
使用某种IDE。但对于初学者来说,过早地使用集成开发工具会影响对程序底层运行机

第 
3 
章 Web 
应用开发基础

59
制的理解,导致在程序出现运行错误时,需要分析原因却无从下手。因此本书没有使用集
成开发工具,而是使用了最简单的开发工具。编写源代码使用文本编辑器软件,推荐使用
EditPlus或UltraEdit,编译Java代码使用JDK 。另外,在第10 章也对IDEA 的使用方法
做了简单介绍。

3.1.2 
运行环境
运行环境是指能够使一个程序顺利运行的所有外部条件之和。运行环境包括符合基
本需要的硬件配置、特定版本的操作系统以及其他系统软件及运行库。JavaWeb应用程
序的运行环境涉及三个方面的需要。首先要能够运行Java代码,由于Java语言的跨平
台特性,所以对硬件和操作系统都没有特定的要求,但需要提供JRE(JavaRuntime 
EnvironmenJav

t,a运行环境)。其次要能够提供Web服务,需要有Web服务器和Web 
浏览器。最后要能够提供应用程序功能,需要有运行相关程序的基础平台,这个平台称为
JSP 引擎。另外,如果程序需要数据库的支持,运行环境还需要包括一种数据库管理
系统。

本书使用的运行环境由JDK8 内置的JRE 、Tomcat9 、通用Web浏览器和MySQL8 
构成。其中,JRE 用来运行Java代码,Tomcat提供Web服务和JSP 引擎服务,MySQL 
提供数据库功能。

3.1.3 
安装和配置JDK 
1.JDK 
简介
1996 年,SUN 公司发布了Java的第一个开发工具包:JDK(JavaDevelopmentKit)
0。JDK 是整个Ja的核心,包括Ja运行环境、a工具和Ja基础类库。

1.avavJavav1998 年,SUN 公司发布了第二代Jv2( aa2), 

J2ME(Java2MicroEditioJavaa平台JDK1.简称Jv包括三个版本: 
n,a2 平台的微型版), 应用于移动、无线及有限资源的环
境;J2SE(aa2Sadriin,aa2 平台的标准版), JJv

JvtnadEdtoJv应用于桌面环境;2EE(aa2 
Eneprisitin,aa2 平台的企业版), aa的应用服务器。

treEdoJv应用于基于Jv2004 年,JDK1.5的发布是Java语言发展史上的里程碑事件。为了表示这个版本的
重要性,5更名为JDK5.内部版本号为1.0)。JDK1.0( 
0。这次,5.
取消了其中的

2006 年,SUN 公司发布了JDK6.Java的各种版本已经更名, 
数字2,J2ME 更名为JavaME(微型版),J2SE 更名为JavaSE(标准版),J2EE 更名为

JavaEE(企业版)。
0版本开始改名为Jv

因为JDK 从6.aaSE,所以我们通常使用的J2SE 也就是标准版
的JDK,与大家经常看到的JavaSE6.6其实都是一回事。

0以及JDK1.2009 年,Oracle(甲骨文)公司收购SUN 公司。从此以后,JDK 的获取就变成了从
Oracle的网站上免费下载,SUN 公司就此退出了历史舞台。
Java目前的最新版本已经更新到JDK17 。但2014 年发布的JDK8 仍然是使用最为
广泛的版本之一,本书也以此版本为主。


60
Java 
Web 
应用开发(第
2 
版)

2.下载JDK 
以下载JDK8的最新版本jdk-u-idsxee为例,打开浏览器,在地址栏

8311wnow-64.x
输入htps://www.rceom/jv/tcnlge/downod/#jaa8后,在打开的页面

oalcaaehooislasv
中,列出了不同版本的JDK 。(.) 单击“Winow选(”) 项卡,选择列表中的jdk8311wnow-64.xe,进入用户登录

ds-u-idsxe
页面,输入用户名和密码进行登录后,开始下载。如果没有用户名,则需要创建一个新用
户,创建新用户的过程在此省略。

JDK支持不同的操作系统及其位数,如Linux、MacOS 、Solaris和Windows,版本列
表中的i586指32位操作系统,x64指64位操作系统,32位操作系统的JDK版本可以在
64位操作系统上使用,反之则不行。所以j-u-indsxexe实际是Wids

dk8311wow-64.now64位操作系统的JDK安装包,不能在Windows32位操作系统上使用。在实际开发中使
用的JDK版本必须与操作系统完全匹配才能将Java的性能发挥到最佳,在学习时则无
须拘泥于此。

3.安装JDK 
-u-idsxee文件, 下一步”
双击下载的jdk8311wnow-64.x在打开的安装界面中单击“ 按
钮,进入定制安装界面,1所示。

如图3.


图3.

1 
JDK 
定制安装

在定制安装界面中可以选择要安装的程序功能,其中“公共JRE”为独立的Java运行
环境,由于JDK中已经包含了JRE,因此可以不安装此功能(单击左侧按钮,在弹出的下
拉列表中选择

)。安装路径采用默认的“C:\PogamFie\Jv\j8.311\”。
rrlsaadk1.0
单击“下一步”按钮,开始安装所选功能,安装完毕后单击“关闭”按钮退出(_) 安装程序。
此时在安装路径“C:\PogamFie\Jv\jdk1.0_” 2所示的目

rrlsaa8.311\下可以看到如图3.
录结构。

.bn目录包含了编译、调试、打包、运行Jaa程序的工具程序。例如jaa.xe为编
ivvce
译Ja源代码的工具,e为运行编译得到的字节码文件的工具。

avjava.ex


第
3 
章 Web 
应用开发基础

61
图3.安装完成后的JDK 
目录结构

2 

.jre目录为前面提到的Java运行环境。
.liaa类编译打包后的基础类库。bn目录下jvee等工具的运行依
b目录为Jviaa.
x
赖于lib目录下的基础类库
。


.sczp文件为Jv
r.iaa类的源代码。

4. 
配置JDK 
以Windows10 系统为例,右击桌面上的“此电脑”图标,选择“属性”,在打开的控制
面板主页左侧选择“高级系统设置”,弹出“系统属性”对话框。然后在“高级”选项卡中单
击“环境变量”按钮,弹出“环境变量”对话框。在该对话框上方的“用户变量”列表中选择Pat(“) h行,(”) 然后单击“编辑”按钮,弹出“编辑环境变量”对话框。单击“新建”按钮,在文本
框中输入“C:\PoramFils\Jaaj8._311\bn”后,依次单击“确定”按钮,返回到控

rgev\dk1.0i
制面板主页,最后关闭该窗口。

把JDK 的bin路径添加到Path环境变量中后,就可以在执行Java的工具程序时自
动在指定的路径下进行搜索并执行,无须每次在命令行输入Java的工具程序全路径,只
输入工具名即可。

5. 
测试JDK 
单击任务栏左下角的


图标,在搜索框中输入“cmd”后按回车键打开命令行窗口。
在命令行输入“jaavrin后按回车键,3所示的JDK 版本信息,
v-eso” 显示如图3.即表示
JDK 安装配置成功。

3.1.4 
安装和配置Tomcat 
1.Tat简介
Tomcat(om) 是(c) 一个开源的轻量级Web应用服务器,是Apache软件基金会(Apache 
SoftwareFoundation)的Jakarta项目中的一个核心项目,由Apache、SUN 和其他一些公


62
Java 
Web 
应用开发(第
2 
版)


图3.

3 
JDK 
版本信息

司及个人共同开发而成。因为Tomcat技术先进、性能稳定,而且免费,因而深受Java爱
好者的喜爱并得到了部分软件开发商的认可,成为了目前比较流行的Web应用服务器, 
在中小型系统和并发访问用户不是很多的场合下被普遍使用,是学习JavaWeb开发的首
选。Tomcat官方网络如图3.

4所示。


图3.t官方网站

4 
Tomca

2.下载Tt 
Tomcat下载(o) 包(c) 分为安装版和绿色版两种。安装版和常规的软件安装包类似,(a) 在安
装向导的提示下进行操作,并会以服务的形式注册到系统,可以很方便地控制Tomcat的
启动、关闭和重启。绿色版则是在解压后需要通过人工方式在配置文件中进行参数的配
置,启动和停止Tomcat都需要通过执行脚本来实现。本书使用绿色版,读者有兴趣也可
以下载安装版进行尝试。本书使用的版本为t54,其下载地址为hs://

omcat-9.0.
tpdldapceog/omct/omct9/9.54/bn/pah-omct9.54wnow-64.ip。

cn.ah.rtata-v0.iaceta-0.-idsxz

3.配置Tat 下载完成后(o) ,(m) 将(c) 其解压缩到某个路径,如C盘根目录。进入解压后的目录“(m) C:\ 
apceta-0.,(”) 可以看到如图3.

ah-omct9.545所示的目录结构。


第3 章 Web 应用开发基础 63 
图3.5 Tomcat目录结构
. bin目录包含了启动、停止等操作Tomcat的程序或者脚本。由于本书采用的是
绿色版,因此在该文件夹下有后缀为.sh和.bat的Tomcat控制程序,其中.sh为
Linux系统下运行的脚本,.bat则为Windows系统下运行的脚本。安装版的控制
程序后缀为.exe。
.conf目录为Tomcat的配置文件夹,最重要的配置文件是server.xml,此文件中配
置了Tomcat的各个端口、应用部署的路径等。
.logs目录为Tomcat运行的日志,在开发和运维时经常需要通过查看此文件夹下
的日志来定位系统出现的问题。
. webapps目录为Tomcat默认部署应用的路径。本书中所有的示例应用都需要部
署到此目录中才能运行。
Tomcat运行需要JDK的支持,因此需要为Tomcat配置JDK的安装路径。右击bin 
目录下的startup.bat,在弹出的快捷菜单中选择“编辑”后,打开该文件,在第一行添加以
下内容即可。 
SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_311 
4.测试Tomcat 
双击bin目录下的startup.bat,启动Tomcat。当出现如图3.6所示的提示信息时,表
示启动成功。
如果界面显示汉字乱码,可以修改conf目录下的logging.properties文件,添加以下
代码,将字符集设置为GBK,重新启动即可。 
java.util.logging.ConsoleHandler.encoding =GBK

64 Java Web 应用开发(第2 版) 
图3.6 Tomcat启动成功提示信息
打开浏览器,在地址栏输入http://localhost:8080,出现Tomcat信息显示页面,如
图3.7所示,说明安装成功。
图3.7 Tomcat信息显示页面
3.2 JSP基本概念
JavaWeb应用开发的基本形式是编写JSP页面。JSP(JavaServerPages,Java服务
器页面)是一种创建和管理动态网页的技术标准。通过在传统的网页HTML文件中插
入Java脚本代码和JSP标记,就可以得到JSP页面文件。JSP程序本质上是在服务器端
执行的JavaServlet,执行完毕通常会返回给客户端一个HTML文件作为响应,客户端浏
览器即可查看该响应文件的内容。
3.2.1 JSP 开发方法
这里用一个简单的示例来说明JSP的开发方法。
【程序3.1】 在“Tomcat安装目录\webapps”下创建demo03文件夹,在其中编写示
例页面文件serverDemo.jsp。 
<%@page contentType="text/html;charset=utf-8" %> 
<%@page import="java.util.Date"%>

第3 章 Web 应用开发基础 65 
<%@page import="java.text.SimpleDateFormat"%> 
<html> 
<head> 
<title>serverDemo</title> 
</head> 
<body> 
<h3>欢迎光临中国北京</h3> 
<% 
SimpleDateFormat df = new SimpleDateFormat( "yyyy - M - d HH: mm: 
ss"); 
%> 
<span id="myspan"><%=df.format(new Date())%></span> 
<hr> 
</body> 
</html> 
serverDemo.jsp文件的功能是输出一行文字和当前的系统时间。
【程序3.2】 在demo03文件夹中编写示例网页文件clientDemo.html。 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<title>JavaScript Date 对象</title> 
<script language="javaScript"> 
function showTime(){ 
var Timer=new Date(); 
var h=Timer.getHours(); 
var m=Timer.getMinutes(); 
var s=Timer.getSeconds(); 
var d=Timer.getDate(); 
var m1=Timer.getMonth()+1; 
var y=Timer.getFullYear(); 
var strShow=""+y+"-"+m1+"-"+d+" "+h+":"+m+":"+s; 
myspan.innerText=strShow; 
} 
</script> 
</head> 
<body> 
<h3>欢迎光临中国北京</h3> 
<span id="myspan">时间内容</span>

66 Java Web 应用开发(第2 版) 
<script> 
showTime(); 
</script> 
<hr> 
</body> 
</html> 
clientDemo.html文件的功能也是输出一行文字和当前的系统时间。
启动Tomcat,打开浏览器,在地址栏输入http://localhost:8080/demo03/serverDemo. 
jsp,可以看到程序3.1 的运行效果,如图3.8 所示,而输入http://localhost:8080/ 
demo03/clientDemo.html,可以看到程序3.2的运行效果,如图3.9所示。
图3.8 serverDemo.jsp页面的运行效果 
图3.9 clientDemo.html页面的运行效果
上面两个程序的运行效果几乎是完全一样的。但它们的源代码完全不同。下面通过
介绍JSP的运行机制和JSP页面构成来分析这两个页面的运行过程。
3.2.2 JSP 运行机制
JSP的运行机制如图3.10所示。当浏览器向服务器发出请求来访问一个JSP页面
时,所请求的JSP文件会被服务器端的JSP引擎转换为一个Java类,并被编译成一个字
节码文件,再装载到Java虚拟机中运行,最后把运行产生的输出作为对本次请求的响应
返回给浏览器。
图3.10 JSP页面执行的处理过程
实际上,服务器并非在每次收到JSP请求后都严格按照上述过程进行处理,而是会

第3 章 Web 应用开发基础 67 
先检查是否为针对该JSP文件创建后的第一次请求,或者所请求的JSP文件在上次被请
求之后是否被更新过。如果是第一次请求,或者被更新过,就会按照上述的处理过程来运
行。如果该JSP文件之前已经被请求过,而且之后没有更新过,就会直接找到该文件对
应的字节码文件来执行。因此,JSP页面在第一次被请求时响应速度会比较慢,之后再次
访问就会快很多。
可以在“Tomcat安装目录\work\Catalina\localhost\demo03\org\apache\jsp”下找
到程序3.1被转译成的Java类文件serverDemo_jsp.java,代码如下: 
package org.apache.jsp; 
import javax.servlet.* ; 
import javax.servlet.http.* ; 
import javax.servlet.jsp.* ; 
import java.util.Date; 
import java.text.SimpleDateFormat; 
public final class serverDemo_jsp 
extends org.apache.jasper.runtime.HttpJspBase 
implements org.apache.jasper.runtime.JspSourceDependent { 
private static final javax.servlet.jsp.JspFactory _jspxFactory = 
javax.servlet.jsp.JspFactory.getDefaultFactory(); 
private static java.util.Map<java.lang.String,java.lang.Long> 
_jspx_ dependants; 
private javax.el.ExpressionFactory _el_expressionfactory; 
private org.apache.tomcat.InstanceManager _jsp_instancemanager; 
public java.util.Map<java.lang.String,java.lang.Long>getDependants() { 
return _jspx_dependants; 
} 
public void _jspInit() { 
_el_expressionfactory =_jspxFactory.getJspApplicationContext 
(getServletConfig().getServletContext()).getExpressionFactory(); 
_jsp_instancemanager = 
org.apache.jasper.runtime.InstanceManagerFactory. 
getInstanceManager(getServletConfig()); 
} 
public void _jspDestroy() { 
}

68 Java Web 应用开发(第2 版) 
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; 
javax.servlet.http.HttpSession session =null; 
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;charset=utf-8"); 
pageContext =_jspxFactory.getPageContext(this, request, response, 
null, true, 8192, true); 
_jspx_page_context =pageContext; 
application =pageContext.getServletContext(); 
config =pageContext.getServletConfig(); 
session =pageContext.getSession(); 
out =pageContext.getOut(); 
_jspx_out =out; 
out.write("\r\n"); 
out.write("\r\n"); 
out.write("\r\n"); 
out.write("<html>\r\n"); 
out.write(" <head>\r\n"); 
out.write(" <title>serverDemo</title>\r\n"); 
out.write(" </head>\r\n"); 
out.write(" <body>\r\n"); 
out.write(" <h3>欢迎光临中国北京</h3>\r\n"); 
out.write("\t "); 
SimpleDateFormat df =new SimpleDateFormat("yyyy-M-d HH:mm:ss"); 
out.write("\r\n"); 
out.write("\t <span id=\"myspan\">"); 
out.print(df.format(new Date())); 
out.write("</span>\r\n"); 
out.write(" <hr>\r\n"); 
out.write(" </body>\r\n");

第3 章 Web 应用开发基础 69 
out.write("</html>"); 
} catch (java.lang.Throwable t) { 
if (!(t instanceof javax.servlet.jsp.SkipPageException)){ 
out =_jspx_out; 
if (out !=null && out.getBufferSize() !=0) 
try { out.clearBuffer(); } catch (java.io.IOException e) {} 
if (_jspx_page_context !=null) 
_jspx_page_context.handlePageException(t); 
} 
} finally { 
_jspxFactory.releasePageContext(_jspx_page_context); 
} 
} 
} 
serverDemo_jsp.java 是一个完整的Java 类。其中只有下面这段代码是来自
serverDemo.jsp,其余的语句都是Tomcat在转译过程中自动生成的。 
out.write("\r\n"); 
out.write("\r\n"); 
out.write("\r\n"); 
out.write("<html>\r\n"); 
out.write(" <head>\r\n"); 
out.write(" <title>JSP Date 对象</title>\r\n"); 
out.write("\r\n"); 
out.write(" </head>\r\n"); 
out.write(" <body>\r\n"); 
out.write(" <h1>欢迎光临中国北京</h1>\r\n"); 
out.write(" \r\n"); 
out.write("\t "); 
SimpleDateFormat df =new SimpleDateFormat("yyyy-M-d HH:mm:ss"); 
out.write("\r\n"); 
out.write("\t <span id=\"myspan\">"); 
out.print(df.format(new Date())); 
out.write("</span>\r\n"); 
out.write("<hr>\r\n"); 
out.write(" </body>\r\n"); 
out.write("</html>"); 
正是通过这种运行机制,原本十分晦涩的JavaWeb服务器端开发变成了简单的JSP 
开发。

70 Java Web 应用开发(第2 版) 
在图3.8所示的运行效果页面中使用浏览器的“查看页面源代码”功能,可以看到浏
览器所收到的响应信息是如下内容。 
<html> 
<head> 
<title>serverDemo</title> 
</head> 
<body> 
<h3>欢迎光临中国北京</h3> 
<span id="myspan">2017-5-7 22:18:04</span> 
<hr> 
</body> 
</html> 
不难看出,上面这段代码正是serverDemo_jsp类的运行产生的输出。其中的大部分
内容与程序3.1完全相同。
JSP页面中可以包含JSP脚本、JSP指令、JSP标记、HTML标记、JavaScript语句以
及CSS样式定义等内容。这些内容可以在一个JSP文件中组合使用。
根据这些代码的运行位置,可以把JSP页面的内容分为服务器端代码和客户端代
码。服务器端代码是指运行在服务器端的JSP脚本、JSP指令和JSP标记等内容。客户
端代码是指需要在客户端的浏览器上运行和处理的HTML标记、JavaScript语句和CSS 
样式定义等内容。
JSP文件存储在服务器端。当浏览器向服务器发出JSP请求后,从上面分析的处理
过程可以看到,JSP页面中的客户端代码在服务器端不做任何处理,服务器端代码则是在
服务器环境下被运行之后,将其所产生的输出与客户端代码组合成一个整体返回给浏览
器,最后由浏览器对接收到的内容进行解析和显示。
由此可知,在程序3.1的运行效果图3.8中所显示的时间是服务器端的当前系统时
间。浏览器只负责把接收到的时间字符串显示在页面中。
而程序3.2是一个HTML文件。Tomcat对这个文件的处理不像JSP文件那么复
杂,只是将文件内容原样返回给浏览器,然后由浏览器对文件内容进行解析和显示。所
以,在运行效果图3.9中所显示的时间是客户端的当前系统时间。
3.2.3 Web 应用目录结构
虽然,JavaWeb应用开发的基本形式是编写JSP页面,但一个典型的JavaWeb应用
通常会包含一组JSP文件、Servlet、其他Java类以及HTML文档和各种资源文件。这些
文件在Web应用中都有固定的存入目录。
按照JavaEE规范的规定,一个典型的JavaWeb应用包含如下4个部分。
. 公开文件夹,存放能够被用户访问的资源,包括.jsp、.htm、.js、.css、.jpg等文件。
. WEB-INF/web.xml文件,为应用的部署描述文件。

第 
3 
章 Web 
应用开发基础

71
.WEBINF/lse存放编译好的Jv.ls)。
-cas文件夹, aa类文件(ca

.WEB-INF/lib文件夹,存放Java类库文件(jar)。
公共文件夹中存放所有可以被用户访问的资件。也可以把这些文件根据类别放
在公共文件夹下的不同子文件夹中。这个公开文件夹的名字就是Web应用程序的名称。
WEB-INF文件夹是一个专用区域,其中的文件用户不能直接访问,只能被Web应用
本身和JSP引擎使用。源文(.) 
运行JavaWeb应用需要先把它部署到运行环境
中。最简单的部署方式是把应用文件夹存放到
Tomcat安装目录下的webapps中。例如,对于本书
中使用的示例应用“新闻发布系统”,在webapps目录
下创建nesu相应的目录结构如图3.

wPb文件夹, 11 
所示。每
个文件夹中放置不同类型的代码文件,具体内图3.nwPb应用的目录结构

11 
esu

容如下。

.newsPub文件夹:是JavaWeb应用的公开文件夹,所有的JSP文件和HTML文
件都直接放在这个文件夹下。
.common文件夹:存放应用中的公共文件,比如通用的JSP文件。此文件夹的名
字不一定必须是common,可以根据需要自行设定。
.cs 
文件夹:存入页面中使用的CSS样式定义文件。
.image文件夹:存放页面文件中使用的图片文件。
.js文件夹:存放页面中使用的JavaScript代码文件。
.WEB-INF文件夹:是JavaWeb应用的安全目录。
.clases文件夹:用于存放JavaWeb应用中用到的Java类字节码文件。
.lib文件夹:用于存放JavaWeb应用中用到的外部jar文件。
.src文件夹:用于存放JavaWeb应用中用到的Java类源文件。这个文件夹及其
中的Java类源文件对于JavaWeb应用的运行不是必需的,只是为了代码管理的
方便,习惯把源文件放置在此处。
把第2章编写的indx.tml放到nesub文件夹中,ic放到cs 
文件夹中,所

ehwPman.
s 
用到的图片文件放到imae文件夹中,ujs文件夹中。然后启动Tomct,

gfn.s放到ja打开
浏览器,在地址栏输入h//oahs8080/esuidx.tl,

tp:lclot:nwPb/nehm即可打开新闻发布
系统首页。
这里直接在运行环境中创建newsPub应用的目录结构,接下来将会在newsPub文
件夹中依次完成各个功能的开发,逐步完善新闻发布系统。

3 
JSP基础语法

3.
JSP页面中的服务器端代码包括JSP脚本、JSP指令、JSP标记等构成元素。这些代
码需要符合JSP语法的要求。


72 Java Web 应用开发(第2 版) 
3.3.1 JSP 脚本元素
所有的JSP脚本元素都以“<%”标记开始,以“%>”标记结束。JSP脚本元素包括
3类,分别是脚本代码、声明和表达式。JSP脚本代码就是一些Java代码片段;JSP声明
包括变量、方法和类的声明,分别用于定义变量、方法和类;JSP表达式用于输出计算结
果。另外,还可以在JSP页面文件中添加不同形式的注释。
1.JSP脚本代码
JSP脚本代码就是一些Java代码片段,可以实现业务逻辑处理,也可以产生输出。
其语法格式如下: 
<% 脚本代码 %> 
一个JSP页面可以有多个脚本代码,这些脚本代码将被JSP引擎按顺序执行。
例如在程序3.1中,就使用了如下代码实现获取系统当前时间的功能。 
<% 
SimpleDateFormat df =new SimpleDateFormat("yyyy-M-d HH:mm:ss"); 
%> 
脚本代码中声明的变量在当前页面内的所有脚本代码和JSP表达式中有效,这样的
变量被称为JSP页面的局部变量。因为这里的变量定义语句在发生JSP转译时,都被转
换成了_service()方法中的语句,所以这些变量实际也相应地转变成了方法中的变量。这
种变量的生存周期仅限于方法的执行过程中。当多个用户请求同一个JSP页面时,一个
用户对JSP页面局部变量的操作,不会影响到其他用户的这个局部变量。
2.JSP声明
前面已经说过,JSP页面在运行时会被首先转译为一个Java类。在JSP声明中所定
义的变量和方法都会成为转译后的Java类的成员变量及类成员方法,声明的类则成为内
部类。所声明的变量、方法和类可以被同一JSP页面中的其他代码访问。
JSP声明的语法格式如下: 
<%! 变量或方法、类的声明%> 
JSP声明中定义的变量也称为JSP页面的全局变量,所有访问同一个JSP页面的客
户操作的都是同一个全局变量。
【程序3.3】 在demo03文件夹下编写示例页面文件declareDemo1.jsp。 
<%@page contentType="text/html;charset=utf-8" %> 
<html> 
<head>

第3 章 Web 应用开发基础 73 
<title>declareDemo1</title> 
</head> 
<body> 
<H3> 
<%! int number=0; %> 
<% 
int localNumber =0; 
localNumber++; 
synchronized(this){ 
number++; 
} 
%> 
您是第 
<%out.println(number); %> 
个访问本页面的客户。局部变量值是 
<%out.println(localNumber);%> 
</H3> 
</body> 
</html> 
declareDemo1.jsp中的声明部分定义了一个变量number。这个number是JSP页面
的全局变量。接下来又在脚本代码中定义了一个局部变量localNumber。
然后分别对两个变量进行加1运算,再进行输出。其中对于全局变量number的操
作,需要进行同步处理。
启动Tomcat,打开浏览器,在地址栏输入http://localhost:8080/demo03/ 
declareDemo1.jsp,查看程序3.3的运行结果,如图3.12所示。在同一个浏览器窗口和不
同的浏览器窗口多次访问该页面,可以看到number 变量的值会依次递增,而
localNumber变量的值一直保持为1。这是因为,局部变量只在处理当前页面请求时有
效,处理完毕则被销毁,而全局变量作为JSP页面对应类的成员变量,会一直存在于内存
中。只有当前应用被停止运行,例如关闭Tomcat时,全局变量才会被销毁。
图3.12 declareDemo1.jsp的运行结果
【程序3.4】 在demo03文件夹下编写示例页面文件declareDemo2.jsp。 
<%@page contentType="text/html;charset=utf-8" %> 
<html> 
<head>

74 Java Web 应用开发(第2 版) 
<title>declareDemo2</title> 
</head> 
<body> 
<H3> 
<%! int number=0; 
synchronized void countPeople(){ 
number++; 
} 
%> 
<% 
int localNumber =0; 
localNumber++; 
countPeople(); 
%> 
您是第 
<%out.println(number); %> 
个访问本页面的客户。局部变量值是 
<%out.println(localNumber);%> 
</H3> 
</body> 
</html> 
declareDemo2.jsp 中的声明部分除了定义全局变量number 之外,还定义了
countPeople()方法。在countPeople()方法中实现对number的加1处理,然后在脚本代
码中调用此方法,最后输出结果。
启动Tomcat,打开浏览器,在地址栏输入http://localhost:8080/demo03/ 
declareDemo2.jsp,查看程序3.4的运行结果,可以看到与程序3.3完全相同。
【程序3.5】 在demo03文件下编写示例页面文件declareDemo3.jsp。 
<%@page contentType="text/html;charset=utf-8" %> 
<html> 
<head> 
<title>declareDemo3</title> 
</head> 
<body> 
<H3> 
<%! 
class Counter { 
int number=0; 
void countPeople(){ 
number++; 
}

第3 章 Web 应用开发基础 75 
} 
Counter c1 =new Counter(); 
%> 
<% 
Counter c2 =new Counter(); 
c1.countPeople(); 
c2.countPeople(); 
%> 
您是第 
<%out.println(c1.number); %> 
个访问本页面的客户。局部变量值是 
<%out.println(c2.number);%> 
</H3> 
</body> 
</html> 
declareDemo3.jsp的声明部分定义了一个Counter类,该类含有成员变量number和
countPeople()方法,并定义了一个全局变量c1。然后在脚本代码中定义了局部变量c2, 
并分别调用c1和c2的countPeople()方法。最后输出结果。
启动Tomcat,打开浏览器,在地址栏输入http://localhost:8080/demo03/ 
declareDemo3.jsp,查看程序3.5的运行结果,也可以看到与程序3.3完全相同。
3.JSP表达式
可以将JSP表达式理解为一种简单的输出形式。JSP表达式的语法格式如下: 
<%=表达式%> 
其中的表达式可以是任意合法的Java表达式。该表达式会被计算并将得到的结果
以字符串的形式显示到页面中。需要注意的是,由于JSP表达式不是程序代码,所以末
尾不能出现分号“;”。
【程序3.6】 在demo03文件夹下编写示例页面文件expressionDemo.jsp,输出九九
乘法表。 
<%@page language="java" contentType="text/html;charset=utf-8" %> 
<html> 
<head> 
<title>expressionDemo</title> 
</head> 
<body> 
<h1>九九乘法表</h1> 
<table>

76 Java Web 应用开发(第2 版) 
<%for (int i=1;i<=9;i++){%> 
<tr> 
<%for (int j=1;j<=i;j++){%> 
<td><%=i%>* <%=j%>=<%=i* j%></td> 
<%}%> 
</tr> 
<%}%> 
</table> 
</body> 
</html> 
expressionDemo.jsp中使用多段脚本代码实现了循环处理,并用JSP 表达式进行
输出。启
动Tomcat,打开浏览器,在地址栏输入http://localhost:8080/demo03/expressionDemo. 
jsp,程序运行结果如图3.13所示。
图3.13 expressionDemo.jsp运行结果
4.注释
除了上面所说的3种组成内容之外,JSP页面中也可以编写必要的注释内容。JSP 
注释的语法如下: 
<%--JSP 注释信息--%> 
这些注释信息在JSP转译为Java类时会被忽略。
另外,在JSP脚本代码中,也可以使用Java的单行注释和多行注释方式添加注释内
容。这些Java注释与其他脚本代码一样,被转换到转译之后的Java类中,然后在编译
Java类时被忽略。

第3 章 Web 应用开发基础 77 
在JSP页面中还可以使用HTML的注释语法编写注释内容,语法如下: 
<!--HTML 注释信息--> 
需要注意的是,HTML注释与普通的HTML标记一样,会作为客户端代码被原样发
送给浏览器。虽然在浏览器窗口中不会显示这些注释内容,但是利用浏览器的“查看页面
源代码”功能就可以看到这些HTML注释。所以,如果不希望被用户看到注释内容,就
需要使用前面两种注释方式。
为了提高程序的可读性,程序员应该合理地使用注释,将代码所实现的算法、功能等
通过注释描述清晰,以提高代码的可读性和可维护性。
【程序3.7】 在demo03文件夹下编写示例页面文件commentDemo.jsp,使用不同的
注释方式。 
<%@page language="java" contentType="text/html;charset=utf-8" %> 
<html> 
<head> 
<title>JSPComment</title> 
</head> 
<body> 
<%--JSP comment --%> 
<h1>hello world</h1> 
<% 
//Java comment1; 
out.println("<h2>hello world</h2>"); 
/*Java comment2*/ 
%> 
<!--html comment--> 
</body> 
</html> 
图3.14 commentDemo.jsp运行结果
commentDemo.jsp中分别使用了JSP注释、Java注释和HTML注释。
启动Tomcat,打开浏览器,在地址栏输入http://localhost:8080/demo03/commentDemo. 
jsp,程序运行结果如图3.14所示。
可以通过查看和对比转译后的Java类、浏
览器接收到的源代码以及浏览器窗口中的显
示,来理解3种注释的处理时机。
3.3.2 JSP 指令元素
JSP指令主要用来通知JSP引擎如何处理
JSP页面,所有指令都是在JSP的整个页面有
效。JSP指令是在JSP文件转译时处理,用于