第4章JSP的语法和语义 本章将详细介绍J S P的语法和语义( J S P 1 . 1)。如果读者接触过A S P或P H P,将会发现J S P的 语法稍显复杂;另一方面,如果读者有J a v a语言程序设计的经验,就会觉得J S P相当简单,其实, 作为J 2 E E的成员,J S P本来就已经成为J a v a的一部分了。 在J S P中,主要包含以下内容: 指令。指令提供该页的全局信息,例如,重要的状态,错误处理,是否是s e s s i o n的一部分等。 声明。页面范围的变量和方法的声明。 脚本。嵌入页面内j a v a代码。 表达式。把表达式变成s t r i n g型以便于包含在页面的输出中。 下面将一一介绍。 4.1 通用的语法规则 J S P的页面是由许多的“元素”组成的,本节描述的语法规则对于这些“元素”都是成立的, 所以称之为“通用”的语法规则,也就是这些元素共有的特性。 4.1.1 元素的语法规则 大部分的J S P元素都基于“ X M L”的语法,这些基于“ X M L”语法的J S P元素一般来说都有 一个包含有元素名称的起始标志,可能还包含有属性设置,一些可选项,和一个结束标志。当 然,J S P页面的起始标记和结束标记一定要在同一个页面中,有的元素也仅仅有一个包含属性设 置的标志,举例如下: <mytag attr1='attribute value' ...> body </mytag> <mytab attr1='attribute value' .../> 读者会发现,前面讲述的To m c a t的配置文件s e r v e r. x m l和w e b . x m l中已经使用了这种语法形 式。 脚本元素则使用的是如A S P般的语法: <%............%> 实际上,每一个J S P页面都应该可以转换为等价的X M L页面,在下一章中将详细介绍作为 X M L的J S P。 J S P元素的属性也和X M L中定义的属性遵从同样的原则, J S P页面的属性值一定要使用引号 括起来,双引号(”)和单引号(')都可以使用。另外,作为替代,也可以使用& a p o s ; 和& q u t o ;来表示双引号和单引号。 4.1.2 JSP中的相对路径 在J S P中,可以使用相对路径来代替绝对路径,在J S P的语法规范中称之为“ U R I”,感兴趣 的读者可以在R F C 2 3 9 6中找到比较完整的描述,这里举几个例子来说明相对路径的概念: 'jspRelativeTest.jsp' '/ jspRelativeTest.jsp' '../ jspRelativeTest.jsp' 在这三行代码中,都假设是在c : t o m c a t J a k a r t a - t o m c a t w e b a p p s e x a m p l e s j s p t e s t . j s p中使用 上述相对路径。 对于第一行代码来说,显然文件j s p R e l a t i v e Te s t . j s p的位置应当为: c : t o m c a t J a k a r t a - t o m c a t w e b a p p s e x a m p l e s j s p j s p R e l a t i v e Te s t . j s p,这是比较容易理解的。但是对于第二行代码就 要注意了,在J S P中,当相对路径以“ /”开头的时候,不是相对于网站的根目录,而是相对于包 含这个J S P文件的We b应用程序的根目录,也就应当是: c : t o m c a t J a k a r t a - t o m c a t w e b a p p s e x a m p l e s j s p R e l a t i v e Te s t . j s p。如果读者对We b应用程序的概念还不清楚,请参见前几章中的相关 章节。第三行代码对于熟悉U N I X或D O S命令行方式的读者应该不陌生,这种情况下,文件 j s p R e l a t i v e Te s t . j s p 的位置应当为: c : t o m c a t J a k a r t a - t o m c a t w e b a p p s e x a m p l e s j s p j s p R e l a t i v e Te s t . j s p。 4.2 注释 一般来说,可以认为在J S P页面中包含有两种不同类型的注释:一种是J S P本身的,用于描述 J S P程序代码,另一种是J S P生成的页面的,也就是H T M L(或W M L . . .)的注释,用于描述J S P页面 执行后的结果页面的功能。H T M L页面的注释这里就不说了,下面是J S P本身的注释语法的例子: <%-- 这是一个JSP的注释--%> 实际上,由于在J S P的“脚本代码”部分中,也就是后面会提到的“ S c r i p t l e t”直接使用 “<% ...... %>”包含起来的部分中可以使用J a v a的语法,所以下面形式的注释也就理所当然的可 以使用了: <% /*这是一个Scriptlet中的注释*/ %> <% /**这也是一个Scriptlet中的注释,可以用Javadoc从生成的Java文件中提取出注释来*/ %> 4.3 指令 前面已经讲过指令在J S P中的地位,指令一般来说有如下的形式: <%@ directive {attr='value'} %> 指令的这种语法形式尽管简单明了,但并不是符合X M L的,第5章将讲述指令的X M L语法。 4.3.1 “p a g e”指令 p a g e指令描述了和页面相关的指示信息。在一个J S P页面中, p a g e指令可以出现多次,但是 第4章J S P的语法和语义91
每一种属性却只能出现一次,重复的属性设置将覆盖掉先前的设置。 p a g e指令的基本语法格式如下: <%@ page page_directive_attr_list %> page_directive_attr_list ::= {language=' scriptingLanguage'} { extends=' className'} { import=' importList'} { session='true|false' } { buffer='none| sizekb' } { autoFlush='true| false' } { isThreadSafe='true|false' } { info=' info_text' } { errorPage=' error_url' } { isErrorPage='true|false' } { contentType='ctinfo' } 下表4 - 1是对这些属性的解释: 表4 - 1 属性名和可选值说明 language = “j a v a” 说language 变量告诉s e r v e r在文件中将采用哪种语言,在J S P当前的规 范(J S P 1 . 1)中,j a v a是J S P唯一支持的语法 extends = “p a c k a g e . c l a s s” 说extends 变量定义了由J S P页面产生的s e r v l e t的父类,一般来说,这 个属性不会用到,但是当需要实现一些特殊功能时,也是比较方便的 说import 变量和任何一个j a v a程序的第一部分一样。同样,它总是被 放在J S P文件的顶部。i m p o r t变量的值是一系列用逗号分开的列表,表 明想要引入的包和类 说注意: 说java.lang.* 说j a v a x . s e r v l e t . * 说javax.Servlet.jsp.* javax.servlet.http.* 说已经缺省地被J S P引擎引入了 session = “t r u e | f a l s e” 说session 变量的缺省值是t r u e,表示当前页面中将有一个缺省的名为 “s e s s i o n”的对象来表示当前会话。“s e s s i o n”对象的类型是: 说javax.servlet.http.HttpSession b u ffer = “n o n e | 8 k b | s i z e k b” 说决定输出流( o u t对象)是否需要缓冲,缺省值是8 k b。与a u t o F l u s h 一起使用 autoFlush = “t r u e | f a l s e” 说确定是否自动刷新输出缓冲,如果设成t r u e,则当输出缓冲区满的 时候,刷新缓冲区而不是抛出一个异常 isThreadSafe = “t r u e | f a l s e” 说缺省值是t r u e,如果多个客户请求发向J S P引擎时,可以一次被处理。 J S P程序员要处理同步时共享的状态,以保证同步时确实是安全的。 说如果i s T h r e a d S a f e被设成f a l s e,则采用单线程模式控制客户端访问该 页 说这没有使你脱离异常分枝,然而,在s e r v e r可能的情况下,通过它 的判断,创建该页的多个实例运行以处理多个装入的客户请求。而且, 这无法保证同一个客户端的连续请求定位到同一个J S P页面的实例上, 在多个页面请求之间的共享资源和状态必须同步 92第一部分JSP 入门
import = “p a c k a g e . * , p a c k a g e . c l a s s” 例如: <%@ page import=”j a v a . u t i l . *” % > (续) 属性名和可选值说明 info = “t e x t” 说页面信息通过页面的S e r v l e t . g e t S e r v l e t I n f o ( )来获得页面可以被访问 的内容的类型 ErrorPage = “p a t h To E r r o r p a g e” 说给出一个J S P文件的相对路径,这个J S P文件用于处理没被处理的例 外。这个J S P文件要把i s E r r o r P a g e设成t r u e。 说需要注意的是: J S P是通过使用S e r v l e t R e q u e s t对象的s e t A t t r i b u t e ( )方 法将名为j a v a x . s e r v l e t . j s p . j s p E x c e p t i o n的对象存储起来实现的。 说另外,当A u t o F l u s h设为t r u e的时候,在J s p Wr i t e r中的数据刷新到 S e r v l e t R e s p o n s e中以后,任何从J S P文件到错误处理文件的未捕获异常 将无法被正常发送 isErrorPage = “t r u e | f a l s e” 说标志一个页面为错误处理页面。设置为t r u e时,在这个J S P页面中的 缺省对象e x c e p t i o n将被定义,其值将被设定为呼叫此页面的J S P页面 的错误对象。缺省为f a l s e 说设置J S P文件和最终文件的m i m e类型和字符集的类型。这一项必须 在文件的前部,任何一个其他字符在文件中出现之前。缺省为: C o n t e n t Type = “t e x t / h t m l ; charset = ISO - 8859 -1” 4.3.2 Include指令 i n c l u d e指令的作用是包含另一个文件,其语法相当简单: <%@ include file='......' %> 在这个指令中应该使用前面讲述的J S P的相对路径表示法。需要说明的是, J S P还有另外一 种包含其他文件的方法: <jsp:include page='' /> 表4 - 2比较了两者的异同: 表4 - 2 语法状态对象描述 <%@ include file=”. . . . . .” % > 编译时包含静态擎J S P引擎将对所包含的文件进行 语法分析 <jsp:include page=”” / > 运行时包含静态和动态擎J S P引擎将不对所包含的文件进 行语法分析 4.3.3 taglib指令 t a g l i b指令用于指示这个J S P页面所使用的标签库,标签库的具体用法属于J S P比较高级的内 容,这里就先不讨论了,先讲述一下基础语法: <%@ taglib uri=' tagLibraryURI' prefix=' tagPrefix' %> 表4 - 3是对各个属性的解释。 第4章J S P的语法和语义93
C o n t e n t Type = “t e x t / h t m l ; charset = ISO - 8859 -1” 表4 - 3 属性说明 u r i 描描述这个标签库位置的U R I,可以是相对路径或绝对路径 t a g P r e f i x 描定义了一个指示使用此标签库的前缀,例如将t a g P r e f i x设为m y P r e f i x时,可以使用 下面的语句来使用此标签库中的m y Ta g标签: < m y P r e f i x : m y Ta g > 描下面这些前缀已经保留: 描jsp:, jspx:, java:, javax:, servlet:, sun:, 和s u n w : 描目前,空的t a g P r e f i x将被忽视 4.4 内置对象 为开发的方便,J S P中内置了一些对象,不需要预先声明就可以在脚本代码和表达式中随意使 用,前面已经接触到的s e s s i o n和e x c e p t i o n就是两个内置对象,表4 - 4详细讲述J S P中的这些内置对象: 表4 - 4 对象类型描述作用域 r e q u e s t j a v a x . s e r v l e t . S e r v l e t R e q u e s t的子类作r e q u e s t(用户请 求期) response j a v a x . s e r v l e t . S e r v l e t R e s p o n s e的子类作p a g e(页面执行 期) p a g e C o n t e x t j a v a x . s e r v l e t . j s p . P a g e C o n t e x t 作p a g e(页面执行 期) s e s s i o n j a v a x . s e r v l e t . h t t p . H t t p S e s s i o n 作s e s s i o n (会话 期) a p p l i c a t i o n j a v a x . s e r v l e t . S e r v l e t C o n t e x t 作a p p l i c a t i o n(整 个We b应用程序运 行期) out j a v a x . s e r v l e t . j s p . J s p Wr i t e r 作p a g e(页面执行 期) c o n f i g j a v a x . s e r v l e t . S e r v l e t C o n f i g 作p a g e(页面执行 期) p a g e j a v a . l a n g . O b j e c t 作P a g e(页面执行 期) e x c e p t i o n j a v a . l a n g . T h r o w a b l e 作p a g e(页面执行 期) 94第一部分JSP 入门
客客户端的请求,通常是H t t p S e r v l e t - R e q u e s t的子类,如果客户的请求中有参 数,则该对象就有一个参数列表 客JSP 页面的响应,是H t t p S e r v l e t R e s - ponse 的子类 客页面的属性和需要通过标准A P I来访 问的相关对象(本质上是构成服务器环 境来让J S P运行的一些对象),以便J S P 引擎来编译页面。但是,不同s e r v e r对 这些属性和对象的实现方式不同 客解决方案是J S P引擎编译用factory 类返 回的服务器的PageContext 类的实现方 法。P a g e C o n t e x t类和r e q u e s t、response 对 象以及p a g e指令的一些属性( e r r o r p a g e , s e s s i o n , b u ff e r, a u t o f l u s h)同时被初始化, 同时提供r e q u e s t请求的相关的对象 客HTTP session 是与r e q u e s t联合的对象 客s e r v l e t的环境通过调用g e t S e r v l e t C o n f i g (). g e t C o n t e x t()方法获得 客代表输出流的对象 客页面的S e r v l e t C o n f i g对象 客指向页面自身的方式(在j a v a代码中 多以t h i s替代) 客没有被T h r o w a b l e捕获的错误。传向 了e r r o r p a g e的U R I
|