第3章〓JSP语法


学习目的与要求

本章主要介绍JSP脚本元素、JSP指令标记和JSP动作标记。通过本章的学习,要求读者理解JSP页面的组成部分,掌握JSP语法,并能够使用JSP开发Web页面。



本章主要内容

 JSP页面的基本构成

 JSP脚本元素

 JSP指令标记

 JSP动作标记


一个JSP页面通常由HTML标记、JSP注释、Java脚本元素以及JSP标记4种基本元素组成。这4种基本元素在JSP页面中是如何被使用的为本章介绍的重点。

本章涉及的JSP页面保存在ch3项目的src/main/webapp目录中。



扫一扫



视频讲解

3.1JSP页面的基本构成
3.1.1一个JSP页面

在HTML静态页面文件中加入和Java相关的动态元素,就构成了一个JSP页面。一个JSP页面通常由以下4种基本元素组成: 

(1) 普通的HTML标记。

(2) JSP注释。

(3) Java脚本元素,包括声明、Java程序片和Java表达式。

(4) JSP标记,例如指令标记、动作标记和自定义标记等。

【例31】根据example3_1.jsp代码中的注释识别JSP页面的基本元素。

example3_1.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

jsp:include page="a.jsp"/  !-- JSP动作标记-- 

%!

int i = 0;//数据声明

int add(int x, int y) {      //方法声明

return x + y;

}

%

html!-- HTML标记--

head

meta charset="UTF-8"

titleInsert title here/title




/head

body

% 

i ++;//Java程序片

int result = add(1, 2);    

%

i的值为%=i%%--Java表达式--%

br

1+2的和为%=result%

/body

/html


a.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleInsert title here/title

/head

body

被example3_1.jsp动态引用。

/body

/html


 3.1.2JSP页面注释

在example3_1.jsp的代码中有许多JSP注释,添加注释能够增强JSP文件的可读性,便于Web项目的更新和维护。JSP页面中常见的注释有以下两种: 

 HTML注释

格式: <!HTML注释>

在标记符“<!”和“>”之间加入注释内容,就构成了HTML注释。

JSP引擎对于HTML注释也要进行处理,即不将它看作注释,如果其中有JSP代码,也将被JSP引擎处理。JSP引擎将处理之后的HTML注释交给客户端,在通过浏览器查看JSP源文件时能够看到HTML注释。

  JSP注释

格式: <%JSP注释%>

在标记符“<%”和“%>”之间加入注释内容,就构成了JSP注释。

JSP引擎将JSP注释当作真正的注释,在编译JSP页面时忽略这部分代码,因此在通过浏览器查看JSP源文件时无法看到JSP注释。

 3.1.3实践环节——识别JSP页面元素

识别出以下JSP页面的基本元素: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

!--学习JSP页面的基本构成--

%!




String content = "JSP页面的基本构成: ";

%

html                          

head

meta charset="UTF-8"

titleshijian3_1.jsp/title

/head

body

%       

content = content + "HTML标记、JSP注释、JSP标记以及Java脚本元素"; 

%

%=content%

/body

/html




扫一扫



视频讲解

3.2JSP脚本元素

JSP中的Java脚本元素包括声明、Java程序片以及Java表达式。

 3.2.1Java程序片

在标记符“<%”和“%>”之间插入的Java代码被称为JSP页面的Java程序片。Java程序片的格式如下: 


% Java代码%


一个JSP页面中可以有任意段Java程序片,这些程序片将被JSP引擎(本书中指Tomcat服务器)按顺序执行。在一个程序片中声明的变量称为JSP页面的局部变量,它们在JSP页面中后继的所有程序片以及表达式内都有效。

当多个用户请求一个JSP页面时,JSP引擎为每个用户启动一个线程,不同的线程会分别执行该JSP页面中的Java程序片,程序片中的局部变量会在不同的线程中被分配不同的内存空间,因此一个用户对JSP页面中局部变量操作的结果不会影响其他用户。Java程序片的执行原理如图3.1所示。




图3.1Java程序片的执行原理


【例32】编写一个JSP页面example3_2.jsp,在页面中存在一段Java程序片,该程序片内声明了一个整型的局部变量n,初始值为0。

example3_2.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_2.jsp/title

/head

body

%              

int n = 0;    

n++;

out.print("n = " + n);    

%          

/body

/html


如果有5个用户请求example3_2.jsp页面,JSP引擎会启动5个线程,页面中的Java程序片在每个线程中都会被执行一次,共执行5次; 在内存中,局部变量n对应5处不同的存储空间,初始值都为0,且都仅执行了一次自加运算,所以5个用户看到的页面效果是相同的。

 3.2.2成员变量与方法的声明

成员变量和方法的声明格式如下: 


%! 变量或方法的定义 %


在标记符“<%!”和“%>”之间声明的变量被称为JSP页面的成员变量,它们可以是Java 语言允许的任何数据类型。例如: 


%! 

int n = 0;

Date date;

%


成员变量在整个JSP页面内都有效(与书写位置无关),因为JSP引擎在将JSP页面转译成Java 文件时将这些变量作为类的成员变量,这些变量的内存空间直到服务器关闭才释放,因此多个用户共享JSP页面的成员变量,任何用户对JSP页面成员变量操作的结果都会影响到其他用户。

在标记符“<%!”和“%>”之间声明的方法被称为JSP页面的成员方法,该方法在整个JSP页面内有效,但是在该方法内定义的变量仅在该方法内有效。

【例33】编写一个JSP页面example3_3.jsp,在该页面中声明一个成员变量n(初始值为0)和方法add()(求两个整数的和),另外该页面中还有一段Java程序片,在程序片中声明一个局部变量m,并且对成员变量n和局部变量m分别进行自加运算。

example3_3.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html




html

head

meta charset="UTF-8"

titleexample3_3.jsp/title

/head

%!

int n=0;

int add(int x,int y){

return x+y;

}

%

body

%

int m=0; 

n++;

m++;

int result=add(1,2);

out.print("成员变量n的值为: "+n+"br");

out.print("局部变量m的值为: "+m+"br");

out.print("1+2="+result+"br"+"br");

out.print("第"+n+"个用户");

%

/body

/html


在example3_3.jsp中,变量n是成员变量,被所有用户共享; 变量m是局部变量,被每个用户独享。如果有3个用户请求这个JSP页面,则看到的效果如图3.2所示。



图3.23个用户请求example3_3.jsp页面的效果


从example3_3.jsp中可知Java程序片具有以下特点: 

(1) 调用JSP页面声明的方法。

(2) 操作JSP页面声明的成员变量。

(3) 声明局部变量。

(4) 操作局部变量。

 3.2.3Java表达式

在标记符“<%=”和“%>”之间可以插入一个表达式,这个表达式必须能求值。表达式的值由Web服务器负责计算,并将计算结果用字符串形式发送到客户端,作为HTML页面的内容显示。

在Java表达式中可以有算术表达式、逻辑表达式、条件表达式等,但在使用Java表达式时需要注意以下两点: 

(1) 不可以在“<%=”和“%>”之间插入语句,即输入的内容不能以分号结束。

(2) “<%=”是一个完整的符号,在“<%”和“=”之间不能有空格。

 3.2.4实践环节——在JSP页面中输出英文字母表

编写一个JSP页面,在JSP页面中使用Java程序片输出小写的英文字母表。

 3.2.5实践环节——网站访问量的统计

利用成员变量被所有用户共享这一性质实现一个简单的计数器,页面效果如图3.3所示。



图3.3简单的计数器


 3.2.6实践环节——打印表格

在浏览器中输出15×10的表格,页面效果如图3.4所示。



图3.415×10的表格




扫一扫



视频讲解

3.3JSP指令标记

常用的JSP指令标记有page指令标记和include指令标记。

 3.3.1page指令标记

page指令标记用来定义整个JSP页面中的一些属性和这些属性的值,可以用一个page指令标记指定多个属性的值,也可以使用多个page指令标记分别为每个属性指定值。page指令标记的语法格式如下: 


%@ page属性1="属性1的值" 属性2="属性2的值" …%


或


%@ page属性1="属性1的值" %

%@ page属性2="属性2的值" %

%@ page属性3="属性3的值" %

…

%@ page属性n="属性n的值" %


page指令标记的属性主要有contentType、import、language和pageEncoding等。

 contentType属性

JSP页面使用page指令标记只能为contentType属性指定一个值,用来确定响应的MIME类型(MIME类型就是设定某种文件用相应的一种应用程序来打开的方式类型)。当用户请求一个JSP页面时,服务器会告诉浏览器使用contentType属性指定的MIME类型来解释执行所接收到的服务器为之响应的信息。例如,当浏览器使用Word应用程序打开用户的请求时,可以将contentType属性值设置为: 


%@page contentType="application/msword;charset=UTF-8"%


常见的MIME类型有text/html(HTML解析器,所谓的网页形式)、text/plain(普通文本)、application/pdf(PDF文档)、application/msword(Word应用程序)、image/jpeg(JPEG图像)、image/png(PNG图像)、image/gif(GIF图形)以及application/vnd.mspowerpoint(PowerPoint应用程序)。

  import属性

在JSP页面中使用page指令标记可以为import属性指定多个值,import属性的作用是为JSP页面引入包中的类,以便在JSP页面的程序片、变量及方法声明或表达式中使用包中的类。

 language属性

language属性用来指定JSP页面中使用的脚本语言,目前该属性的值只能取"java"。

 pageEncoding属性

contentType中的charset是指服务器发送给浏览器时用户所见到的网页内容的编码; pageEncoding是指JSP文件存储时所用的编码。

在JSP规范中,如果pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则由contentType属性中的charset决定,如果charset也不存在,JSP页面的字符编码方式采用默认的ISO88591。

【例34】编写一个JSP页面example3_4.jsp,当用户请求该页面时,在Eclipse内嵌的浏览器中启动本地的PowerPoint应用程序打开该页面。

example3_4.jsp的代码如下: 


%@ page language="java" contentType="application/vnd.ms-powerpoint; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_4.jsp/title

/head

body

在学习page指令标记时,请记住只能为JSP页面设置一个contentType属性值,可以为import属性设置多个值。

/body

/html


 3.3.2include指令标记

一个网站中的多个JSP页面有时需要显示同样的信息,例如该网站的Logo、导航条等,为了便于维护网站程序,通常在这些JSP页面的适当位置嵌入一个相同的文件。include指令标记的作用就是将JSP文件、HTML网页文件或其他文本文件等静态嵌入当前的JSP网页中,该指令标记的语法格式如下: 


%@include file="文件的URL"%


所谓静态嵌入就是“先包含后处理”,在编译阶段完成对文件的嵌入,即先将当前JSP页面与要嵌入的文件合并成一个新的JSP页面,然后由JSP引擎将新页面转化为Java文件处理并运行。



图3.5include指令标记的使用

【例35】编写两个JSP页面example3_5.jsp和example3_5_1.jsp,在example3_5.jsp页面中使用include指令标记静态嵌入example3_5_1.jsp页面,访问example3_5.jsp页面,运行效果如图3.5所示。

example3_5.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_5.jsp/title

/head

body

静态嵌入example3_5_1.jsp之前

br

%@include file="example3_5_1.jsp"%

br

静态嵌入example3_5_1.jsp之后

/body

/html


example3_5_1.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_5_1.jsp/title

/head

body

font color="red" size=4example3_5_1.jsp文件的内容/font

/body

/html


example3_5.jsp页面静态嵌入example3_5_1.jsp页面,需要先将example3_5_1.jsp中的所有代码嵌入example3_5.jsp的指定位置,形成一个新的JSP文件,然后将新文件提交给JSP引擎处理,如图3.6所示。



图3.6静态嵌入的原理


在使用include指令标记时,需要注意嵌入文件后必须保证新合成的JSP页面符合JSP的语法规则,比如例35的example3_5.jsp和example3_5_1.jsp两个页面的page指令标记就不能指定不同的contentType值,否则合并后的JSP页面就使用两次page指令标记为contentType属性设置了不同的属性值,导致语法错误。



图3.7导航栏的运行效果

 3.3.3实践环节——制作导航栏

编写3个JSP页面index.jsp、main.jsp和head.jsp,在index.jsp和main.jsp页面中分别使用include指令标记静态嵌入head.jsp(导航栏)。导航栏的运行效果如图3.7所示。



扫一扫



视频讲解

3.4JSP动作标记


常用的JSP动作标记有include、forward、param、useBean、getProperty和setProperty,其中useBean、getProperty和setProperty将在本书的第5章中介绍。

 3.4.1include动作标记

动作标记include的作用是将JSP文件、HTML网页文件或其他文本文件等动态嵌入当前的JSP网页中。该动作标记的语法格式如下: 


jsp:include page="文件的URL"/


或


jsp:include page="文件的URL"

子标记

jsp:include/


当动作标记include不需要子标记时使用上述第一种形式。

所谓动态嵌入就是“先处理后包含”,在运行阶段完成对文件的嵌入,即在将JSP页面转译成Java文件时并不合并两个页面,而是在Java文件的字节码文件被加载并执行时才去处理include动作标记中引入的文件。与静态嵌入相比,动态嵌入的执行速度稍慢,但是灵活性较高。

【例36】编写两个JSP页面example3_6.jsp和example3_6_1.jsp,在example3_6.jsp页面中使用include动作标记动态嵌入example3_6_1.jsp页面,运行example3_6.jsp页面。

example3_6.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html




head

meta charset="UTF-8"

titleexample3_6.jsp/title

/head

body

动态嵌入example3_6_1.jsp之前

br

jsp:include page="example3_6_1.jsp"/

br

动态嵌入example3_6_1.jsp之后

/body

/html



example3_6_1.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_6_1.jsp/title

/head

body

font color="red" size=4example3_6_1.jsp文件的内容/font

/body

/html


页面文件example3_6.jsp通过动作标记include动态嵌入了example3_6_1.jsp,此时JSP引擎不会将两个文件合并成一个JSP页面,而是分别将文件example3_6.jsp和example3_6_1.jsp转化成对应的Java文件和字节码文件。当JSP解释器解释执行example3_6.jsp页面时会遇到动作指令<jsp:include page="example3_6_1.jsp"/>对应的代码,此时才会执行example3_6_1.jsp页面对应的字节码文件,然后将执行的结果发送到客户端,并由客户端负责显示这些结果,所以example3_6.jsp和example3_6_1.jsp页面中page指令标记的contentType属性值可以不同。

 3.4.2forward动作标记

动作标记forward的作用是从该标记出现处停止当前JSP页面的继续执行,转而执行forward动作标记中page属性值指定的JSP页面。该动作标记的语法格式如下: 


jsp: forward page="文件的URL"/


或


jsp: forward page="文件的URL"

子标记

/jsp: forward 


当动作标记forward不需要子标记时使用上述第一种形式。

【例37】编写3个JSP页面example3_7.jsp、oddNumber.jsp和evenNumbers.jsp,在example3_7.jsp页面中随机获取0~10的整数,当该整数为偶数时转向页面evenNumbers.jsp,否则转向页面oddNumber.jsp。首先访问example3_7.jsp页面。

example3_7.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_7.jsp/title

/head

body

%

long i = Math.round(Math.random() * 10);

if(i%2 == 0){

System.out.println("获得的整数是偶数,即将跳转到偶数页面evenNumbers.jsp。");

%

jsp:forward page="evenNumbers.jsp"/

%

System.out.println("我是偶数,尝试一下能看到我吗?");

}else{

System.out.println("获得的整数是奇数,即将跳转到奇数页面oddNumber.jsp。");

%

jsp:forward page="oddNumber.jsp"/

%

System.out.println("我是奇数,尝试一下能看到我吗?");

} 

%

/body

/html


evenNumbers.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleevenNumbers.jsp/title

/head

body

我是偶数页。

/body

/html


oddNumber.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleoddNumber.jsp/title

/head

body

我是奇数页。

/body

/html


 3.4.3param动作标记

动作标记param不能单独使用,但可以作为include、forward动作标记的子标记来使用,该动作标记以“名字值”对的形式为对应页面传递参数。该动作标记的语法格式如下: 


jsp:父标记page="接收参数页面的URL"

jsp:param name="参数名" value="参数值"/

/jsp:父标记


接收参数的页面可以使用内置对象request调用getParameter("参数名")方法获取动作标记param传递过来的参数值。内置对象将在本书的第4章中介绍。

用户可以使用param子标记向页面传递多个参数,格式如下: 


jsp:父标记  page="接收参数页面的URL"

jsp:param  name="参数名1"  value="参数值1"/

jsp:param  name="参数名2"  value="参数值2"/

jsp:param  name="参数名3"  value="参数值3"/

…

/jsp:父标记


【例38】编写两个页面example3_8.jsp和computer.jsp,在页面example3_8.jsp中使用include动作标记动态包含文件computer.jsp,并向它传递一个矩形的长和宽; computer.jsp接收到参数后计算矩形的面积,并显示结果。

example3_8.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titleexample3_8.jsp/title

/head

body

加载computer.jsp页面计算矩形的面积brbr

jsp:include page="computer.jsp"

jsp:param value="10" name="length"/ 

jsp:param value="6" name="width"/ 

/jsp:include

/body

/html


computer.jsp的代码如下: 


%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%

!DOCTYPE html

html

head

meta charset="UTF-8"

titlecomputer.jsp/title

/head

body

%

String m = request.getParameter("length");




String n = request.getParameter("width");

double a = Double.parseDouble(m);

double b = Double.parseDouble(n);

out.print("我是被加载的页面,负责计算矩形的面积" + "br");

out.print("给我传递的矩形的长度是:"+a+",宽度是:" + b + "br");

out.print("矩形的面积是:" + a * b);

%

/body

/html


 3.4.4实践环节——include和param动作标记的应用

编写3个JSP页面input.jsp、first.jsp和second.jsp,将3个JSP文件保存在同一个Web服务目录中,input.jsp使用include动作标记加载first.jsp和second.jsp页面。first.jsp页面可以画出一个表格,second.jsp页面可以计算出两个正整数的最大公约数。当first.jsp被加载时获取input.jsp页面中include动作标记的param子标记提供的表格的行数和列数,当second.jsp被加载时获取input.jsp页面中include动作标记的param子标记提供的两个正整数的值。

 3.4.5实践环节——登录验证

编写3个JSP页面login.jsp、validate.jsp和success.jsp,login.jsp输入用户名和密码信息,提交给validate.jsp进行用户验证,如果验证为合法用户(用户名为tom,密码为jenny),则转到(forward动作标记)success.jsp页面,否则转到login.jsp页面重新登录。

本章小结

本章主要介绍了JSP页面的组成、JSP脚本元素和JSP标记。一个JSP页面通常由HTML标记、JSP注释、Java脚本元素以及JSP标记组成。JSP脚本元素包括Java程序片、JSP页面成员变量与方法的声明、Java表达式。JSP标记包括指令标记和动作标记。

习 题 3