JSP规范

6.3.1  JSP的发展史
在JSP规范的发展史上,JSP与Servlet规范渊源极深。对于JSP技术而言,1998年是关键的一年,在这一年中,JSP诞生,推出3个beta版的JSP规范。1999年6月,成熟版JSP 1.0版发布。1999年12月,1.1版接踵而至。2001年9月,1.2版发布。当前JSP版本是2.0版。

6.3.2  JSP规范详解
JSP技术帮助开发人员创建企业应用程序的表示部分,允许方便地生成动态清晰的内容。在HTML内容中嵌入Java代码是JSP技术的思想灵魂。JSP规范和平台允许JSP的设计人员根据应用程序需要的动态内容,在HTML页面中嵌入任意数量的Java代码。实践证明,这种方法具有神奇的效果。JSP设计允许分开编写HTML代码和Java代码,之后,可将它们糅合在一起,生成JSP页。JSP技术由此获得长足发展,它的一些高级功能可帮助开发人员快捷地生成动态内容。

在客户端访问JSP页时,需要经历以下两个阶段:

●     转换阶段

●     执行阶段

这两个阶段如图6-16所示。

JSP规范

图6-16  在Web环境中,执行JSP组件的各个阶段。容器右上角显示起初的JSP页。这个JSP页的部

署分为两个阶段。“转换阶段”将JSP转换为Servlet类源文件。“执行阶段”将Java源代码编

译为特殊Servlet类字节码。Web服务器的JVM将这个显示在本图容器右下角的类作为特殊

Servlet加载,以响应服务请求

1. 转换阶段
在这个阶段,Web容器正确解释JSP页的内容,将指定JSP页转换为等效的特殊Servlet源文件。有必要指出,解释过程应生成语法和语义上准确无误的Java页面。如果这个阶段出现了错误,那么就将无法创建Servlet类,更无法将JSP页提供给客户端。

2. 执行阶段
在这个阶段,Web容器将编译Servlet Java文件。必须确保不出现编译错误,并正确生成Servlet字节码。接着,将Servlet加载到Web容器JVM,实例化JSP。此时的JSP已经可以接受客户请求。

在成功编译后,JSP页蜕变为多线程Servlet,交由Web容器中的JSP引擎执行。这个特殊Servlet包含3个重要方法,以控制JSP页的生命期,如下:

●     jspInit()

●     jspDestroy()

●     _jspService()[7]

3. JSP语法
JSP页通过特殊标记“<%”和“%>”使用“脚本元素”,脚本元素通过适当方式嵌入HTML元素标记。Web容器中的JSP引擎能恰如其分地解释特殊标记。在引入脚本元素时,要谨慎从事,以防破坏HTML元素的语法规则。JSP技术的脚本元素分为以下5种。

注释。注释类型有3种:HTML注释、JSP页注释和Java语言注释。JSP注释和Java语言注释显示在脚本标记“<%”和“%>”中,HTML注释不在脚本元素中显示。JSP注释供开发人员参考使用,在成功编译JSP页后,它们将不再出现。

指令(directive)标记。指令标记为转换阶段提供全局信息,其语法如下:

<%@ directive %>

指令类型有3种:page指令、include指令和taglib指令。下面是一个page指令例子:

<%@ page session=false %>

声明(declaration)标记。声明标记允许在脚本标记“<%”和“%>”中引入Java程序以及与Java相关的声明。下面是一个声明例子:

<%! public static final double pi = 3.1415926535897932; %>

这是一个Java声明变量pi的简单表示。Java使用的任何声明类型均可在这个标记中显示,如类变量、实例变量、实例方法、静态方法和内部类等。规范没有限制声明标记中的Java代码。但编写者要谨慎行事,勿将不必要的Java代码写入声明标记。

Scriptlet标记。Scriptlet标记允许将任何Java代码嵌入“<%”和“%>”标记中。开发人员要注意,输入代码将转换为_jspService()方法的一部分。通过精心设计,可将Scriptlet标记与HTML元素巧妙地结合在一起,以便在执行_jspService()方法时生成需要的动态输出。

表达式(express)标记。表达式标记包含Java语言表达式的特定部分,在运行时,经过计算表达式生成输出。通过精心设计,可将表达式标记与HTML元素巧妙地结合在一起,以设置所需的输出格式。下面是一个表达式标记例子:

<%= (pi*5*5)/4 %>

注意,与Scriptlet标记不同,表达式不以“;”结尾。

4. 对象、隐性对象和作用域
JSP技术允许在服务器端创建对象,并使用某些隐性对象提供动态内容。不过,并非JSP页的所有部分都可以访问所有对象。图6-17显示了不同JSP对象的作用域。在使用这些对象时,开发人员要认真予以分析。在JSP创建的对象可能在以下作用域中访问。

JSP规范

图6-17  JSP不同隐性对象的作用域。不同作用域的隐性对象具有不同的生命期。例如,如粉红色栏

        所示,“页”作用域的隐性对象仅用于单个JSP页;而“应用程序”作用域的对象可在整个

Web应用程序生命期内使用

作用域

页作用域。页作用域的对象只允许在所建页面中访问。对象引用存储在pageContext中。在将响应返回给客户端时,将释放对象的所有引用。

请求作用域。如果多个页面服务同一个请求,那么,请求作用域的对象可供这些JSP页访问。请求作用域的范围比页作用域大。同样,在将响应返回给客户端时,将释放这些对象的所有引用。

会话作用域。会话对象域的范围比请求对象域大。会话包含多个请求/响应操作,参与会话的所有页面都可以访问会话对象域对象。会话作用域对象的引用存储在隐性对象session中。在会话完成后,将释放该对象的所有引用。

应用程序作用域。在Web应用程序活动期间,应用程序作用域的对象将一直存在。特定应用程序的所有Web组件都可以访问这些对象。

隐性对象

这些对象可以简化开发人员的工作,可用于Scriptlet和表达式。下面列举了一些重要的隐性对象。

请求对象。表示HttpServletRequest对象,该对象的作用域是“请求”。

响应对象。表示HttpServletResponse对象,该对象的作用域是“响应”。

pageContext对象。表示JSP的页上下文。该对象的作用域是“响应”。

对话对象。HttPSession类型的对象,用于请求客户端。该对象的作用域是“会话”。

应用程序对象。ServletContext类型的对象,用于Web应用程序。该对象的作用域是“应用程序”。

out对象。该对象的作用是将输出写入输出流。作用域是“页”。

6.3.3  JSP标准动作
JSP标准动作(JSP Standard Action)允许执行更高级的任务,例如,不在JSP页中编写Java代码就能实例化对象,并与其他服务器端资源(如JSP页和Servlet)通信。利用特殊的JSP标记,不必编写过多的Java代码,就能在JSP页中完成“标准”操作。

虽然可以在Scriptlet中用Java代码执行操作,但操作标记能促进重用,提高JSP页的易维护性。标准动作主要用于减少JSP页的Java代码内容,标准动作标记极大地依赖于JavaBean组件架构。这些组件采用设计完好的命名模式,在JSP上下文中特别有用。

典型的JSP标准动作语法如下:

<jsp:useBean id='bean' class='beanClass' />

注意,这些标记不同于标准JSP标记“<%”和“%>”。所有标准动作标记都用jsp作为前缀,如jsp:useBean。下面介绍一些标准标记及其在JSP页中的用法。

1. jsp:useBean标准动作
通过这个标准动作,可用指定实例名和类名创建Java对象实例。这个标准动作的一个语法例子如下:

<jsp:useBean id='order' scope='session' class='OrderBean'/>

这个标准动作用于实例化一个Java对象,准确地讲,是一个JavaBean对象。实例名将为order。Java类为OrderBean,供实例化Bean之用;实例作用域是“会话”。

2. jsp:setProperty标准动作
这个标准动作用于设置Bean属性的值,下面是这个标准动作的一些例子:

<jsp:setProperty name='order' property='orderNumber' value='1234' />

<jsp:setProperty name='order' property='*' />

这两个例子运用不同方式设置典型JavaBean属性的值。在两种情况下,标准动作的name确认Bean名称(name='order'),property确认属性名称(property='orderNumber')。可用这个语法设置Bean的所有属性。如果属性非常多,可采用第二种方法,以便用HTML表单的可用匹配属性值,自动设置Bean属性的值。

3. jsp:getProperty标准动作
可利用这个标准动作访问Bean属性。它将JavaBean实例的属性转换为Java String对象,将值放入隐性对象out。

下面是这个标准动作标记的一个例子:

<jsp:getProperty name='order' property='orderNumber'/>

本例将检索order Bean实例orderNumber属性的值。检索值被转换为Java String对象。

4. jsp:include标准动作
这个标准动作将同一上下文的静态和动态资源包含进来。需指定page属性,这个属性的内容是一个相对URL,由Web容器解释。内容将包含在隐性对象out的当前值中。

下面是一个演示jsp:include标准动作用法的例子:

<jsp:include page='/docs/disclaimer.html' flush='true' />

本例是将docs目录的disclaimer.html静态页面包含进来。

5. jsp:forward标准动作
这个标准动作使用page属性,在运行时,将当前请求发送给另一个静态资源,如与当前JSP页处在同一上下文的JSP页或Servlet类。page属性将相对URL作为要转发的值。

下面是一个例子,演示jsp:forward标准动作的用法:

<jsp:forward page='/reports/quarterly.jsp'/>

在本例中,标准动作将请求转发给另一个名为quarterly.jsp的JSP页。

6. jsp:param标准动作
这个标准动作只能在3个标准动作中使用:jsp:include、jsp:forward和jsp:plugin。它提供键-值对,供jsp:plugin、jsp:include和jsp:forward标准动作使用。

下面的例子演示其用法:

<jsp:include page='/docs/copyright.html' >

<jsp:param year='current' value='2004'>

</jsp:include>

7. jsp:plugin标准动作
这个标准动作允许生成HTML代码,HTML代码包含与客户浏览器相关的对应结构,如OBJECT或EMBED,可根据需要下载Java插件,接着执行相应的Applet或JavaBean。如前所述,这个标准动作能根据需要使用其他标准动作,如jsp:param 和jsp:fallback。

<jsp:plugin type='applet' code='Calculator.class' codebase='/itCalc'>

<jsp:param name='employee' . . . />

<jsp:fallback> <B>! Unable to load Calculator Object !</B>

</jsp:fallback> </jsp:plugin>

在本例中,如果插件成功启动,并成功加载Applet,则Applet从param标记获得参数,并成功地显示计算器Applet。如果插件因任何原因未能启动,则HTML页将显示下列消息:

! Unable to load Calculator applet !

如果插件成功启动,而因其他原因Applet不能加载,则Applet窗口将显示常见的ClassNotFoundException。

6.3.4  JSP文档
根据XML语法调整格式的JSP页称为JSP文档(JSP document)。此类文档的特殊性在于,它们是识别“命名空间”的文档,不是普通的JSP页。

为此,可将JSP文档称为“XML视图”。JSP文档的另一个优势在于由识别XML的工具操纵。JSP文档在语法中将jsp:root用作特殊元素(不是标准动作),并作为JSP文档自身的根元素。JSP文档包含JSP指令元素、JSP脚本元素、JSP标准动作、JSP定制操作、jsp:text元素和其他XML部分。

JSP文档内部使用的其他元素如下:

●     jsp.directive.page

●     jsp.directive.include

●     jsp.declaration

●     jsp.scriptlet

●     jsp.expression

注意,上述元素对应于标准JSP标记,如page指令标记、include指令标记、scriptlet和expression等。这些元素有效消除了非XML类型标记,代之以XML标记,从而有助于实现JSP页的“XML化”。

1. 标记扩展
标记扩展是JSP技术的高级概念。标记扩展提供“标记库”工具,该库包括可移植运行时支持,以及验证机制和编写工具支持。使用“定制标记”,不必做太多工作,就能在JSP页引入特殊操作。“定制标记”和“标记库”有助于取消标准JSP页的大多数脚本元素。定制标记库是“定制标记处理器”和“标记库描述符”文件的集合。

定制标记也使用XML语法。这些标记遵循4个基本原理,如下。

标准标记结构。定制标记需要符合以下结构:

<tagPrefix:tagName tagAttribute='value'|'value'*>

tagBody

</tagPrefix:tagName>

空标记结构。空标记结构需要符合下列结构:

<tagPrefix:tagName tagAttribute='value'|'value'*/>

区分大小写。所有标记名、属性和标记前缀都区分大小写。

嵌套规则。应严格采用层次化嵌套方式。定制库标记包含两个部分。jar文件包含“标记处理器”类文件和“标记库描述符(TLD)”文件。TLD是一个XML文档,用于命名和声明定制标记库各个标记的结构。为了有效地使用这些标记库,要做到以下两点:

●     在Web应用程序部署描述符中声明TLD的位置

●     在相应JSP页使用taglib指令,以指示URI及前缀属性

2. 标记处理器
“标记处理器”是一个Java类文件,用于实现如下接口:Tag、IterationTag或BodyTag。接口的实现可在JSP页中提供定制的动作。

Tag接口。这个接口有助于定义所有标记处理器需要的基本方法。该接口提供了4个常量SKIP_PAGE、EVAL_PAGE、SKIP_BODY和EVAL_BODY_INCLUDE,以及两个重要方法doStartTag()和doEndTag(),以帮助实现所需的操作。

IterationTag接口。该标记是基本Tag接口的扩展,提供一个EVAL_BODY_AGAIN变量以及一个附加的方法doAfterBody(),以达到迭代的目的。

你可能感兴趣的:(应用服务器,jsp,bean,servlet,嵌入式)