第五章 JavaServer Page文档

第五章 JavaServer Page文档

JSP文档是使用XML格式编写的JSP页面,使用与第4章所述的标准JSP语法所不同XML语法。JSP文档也是一个XML文档,为我们提供了一些XML相关的好处:

l       可以使用任何的XML工具编写,并能够保证很好的XML兼容性

l       可以进行校验,使文档能够符合文档类型定义(DTD,document type definition

l       可以在文档中使用命名空间

l       可以在运行时进行基于XML的数据交换

除以上优点之外,XML语法能够为页面的作者降低复杂程序,使页面编写变得更加灵活。例如,页面作者可以把某个XML文档当作JSP文档来作用。而且,标准语法的JSP页面中也可以使用XML语法格式的元素,为JSP页面到JSP文档提供了渐进的转换。

本章详细讲述了JSP文档的优势,通过一个简单的示例展示了创建JSP文档是怎样的容易。

你也可以使用XML语法编写标签文档。本章只会讲述JSP文档,至于如何使用XML语法编写标签文件将会包含在下一版本的教程中。

 

JSP文档的示例

本意使用Duke书店的第5个版本——bookstore5以及books程序来演示如何编写JSP文档。在bookstore5程序中,使用了JSTL中的XML标签从一个XML流中获得图书数据。books程序中的books.jspx文档用于访问数据库,并将数据转换为XML流,bookstore5中的页面则可以通过该XML流得到图书数据。

这些程序将会展示产生XML数据以及在Web程序之间传递是多么容易。Books程序可以被看成是书店创建所使用的软件。而bookstore5则是用于零售的服务器。这样,客户通过bookstoreWeb站点就能够看到仓库中的现有的图书资料。

创建JSP文档

一个JSP文档也是一个XML文档,所以必须符合XML标准。也就是说,JSP文件必须具有合法的XML格式,每个开始标记都有相应的结束标记,文档中有且仅有一个根元素。此外,JSP文档中的JSP元素也必须使用合法的XML语法。

大多数JSP语法具有XML兼容的语法格式,下表中列出了不兼容的语法并给出了替代语法格式。由此可见,创建JSP文档比起创建JSP页面困难不了多少,如果你知道如何创建JSP页面,你也可以很容易地创建出JSP文档。

语法元素

标准语法

XML语法

注释

<%-- … --%>

<!-- … -->

声明

<%! … %>

<jsp:declaration>
 
</jsp:declaration>

页面指令

<%@ include … %>

<jsp:directive.include … />

<%@ page … %>

<jsp:directive.page … />

<%@ taglib … %>

Xmlns:prefix=”tag library URL”

表达式

<%= … %>

<jsp:expression> … </jsp:expression>

脚本

<% … %>

<jsp:scriptlet> … </jsp:scriptlet>

 

为了展示从标准语法转换为XML语法是多么简单,下面我们将一个JSP页面转换为一个JSP文档。下面是文件的标准语法内容:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<html>

  <head><title>Hello</title></head>

  <body bgcolor="white">

    <img src="duke.waving.gif">

    <h2>My name is Duke. What is yours?</h2>

    <form method="get">

      <input type="text" name="username" size="25">

      <p></p>

      <input type="submit" value="Submit">

      <input type="reset" value="Reset">

    </form>

    <jsp:useBean id="userNameBean" class="hello.UserNameBean"

        scope="request"/>

    <jsp:setProperty name="userNameBean" property="name"

        value="${param.username}" />

    <c:if test="${fn:length(userNameBean.name) > 0}" >

      <%@include file="response.jsp" %>

    </c:if>

  </body>

</html>

接下来是XML语法格式的内容:

<html

  xmlns:c="http://java.sun.com/jsp/jstl/core"

  xmlns:fn="http://java.sun.com/jsp/jstl/functions" >

  <head><title>Hello</title></head>

  <body bgcolor="white" />

  <img src="duke.waving.gif" />

  <h2>My name is Duke. What is yours?</h2>

  <form method="get">

    <input type="text" name="username" size="25" />

    <p></p>

    <input type="submit" value="Submit" />

    <input type="reset" value="Reset" />

  </form>

  <jsp:useBean id="userNameBean" class="hello.UserNameBean"

    scope="request"/>

  <jsp:setProperty name="userNameBean" property="name"

    value="${param.username}" />

  <c:if test="${fn:length(userNameBean.name) gt 0}" >

    <jsp:directive.include="response.jsp" />

  </c:if>

  </body>

</html>

如上所示,一些标准语法的格式被转换为XML语法:

l       Taglib指定被移除。标签库使用XML命名空间来声明

l       没有结束标记的imginput标签使用了XML兼容的结束标签“/

l       表达式中的“>”替换为了“gt”运算符

l       Include页面被替换为XML兼容的jsp:directive.include标签

经过以上转换之后,如果你将内容存为带有“.jspx”扩展名的文件,那这个文件就是一个JSP文档了。

结合前一节中所述的示例,本章的其余部分将会详细讲述如何将标准语法转换为XML语法。包括如何使用XML命名空间声明标签库、如何使用include指令、创建静态与动态内容等,本章还将介绍两个在JSP文档中专用的标签:jsp:rootjsp:output

 

声明标签库

本节介绍如何使用XML命名空间来声明标签库。

在标准语法中,使用taglib指令来声明使用的标签库,如下:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

但这个语法不符合JSP文档的规范。在JSP文档中声明标签库必须使用xmlns属性指定命名空间:

...

xmlns:c="http://java.sun.com/jsp/jstl/core"

...

属性的值用于表示标签库的标识形式,有以下三种方式:

l       简单的URI,用于唯一标识出该标签库。WEB容器将会在web.xml文件中寻找匹配的标签库的<taglib-uri>元素,或者在WEB-INF/lib(或WEB-INF)目录下功的标签库描述符(TLD文件)中寻找匹配项

l       使用urn:jsptld:path方式,指定一个标签库文件,如:

xmlns:u="urn:jsptld:/WEB-INF/tlds/my.tld"

l       使用urn:jsptagdir:path方式,文件路径必须使用“WEB-INF/tags”开头,标签文件必须使用tag扩展名并放置在WEB-INF/tags目录或它的子目录下

xmlns:u="urn:jsptagdir:/WEB-INF/tags/mytaglibs/"

你可以在JSP文档中的任何元素上使用xmlns属性,这样做有以下一些优势:

l       遵循了XML标签,可以很容易地将XML文档当作JSP文档使用

l       有必须的确话,可以覆盖某个元素的命名空间

l       允许使用xmlns声音其它的命名空间,而不仅仅是标签库

books.jspx页面中使用了xmlns属性在根元素——books上声明了以下标签库:

<books

  xmlns:jsp="http://java.sun.com/JSP/Page"

  xmlns:c="http://java.sun.com/jsp/jstl/core"

>

这样一来,页面中所有元素都可以使用这些标签库。

当然,你也可以局部声明命名空间:

<books>

...

  <jsp:useBean xmlns:jsp="http://java.sun.com/JSP/Page"

            id="bookDB"

            class="database.BookDB"

            scope="page">

    <jsp:setProperty name="bookDB"

            property="database" value="${bookDBAO}" />

  </jsp:useBean>

  <c:forEach xmlns:c="http://java.sun.com/jsp/jstl/core"

          var="book" begin="0" items="${bookDB.books}">

          ...

  </c:forEach>

</books>

此时,jsp前缀只能在jsp:userBean元素及其子元素中使用。同样,c前缀也只能在c:forEach元素中使用。

局部命名空间还允许覆盖使用前缀。例如,在页面中的其它部分,你可以绑定c前缀到一个不同的命名空间或标签库。不同的是,jsp前缀必须绑定到命名空间http://java.sun.com/JSP/Page

 

JSP文档中的包含指令

页面指令用于传递信息给容器并影响容器对JSP页面的编译操作。页面指令本身并不会出现在XML输出中。

有三种页面指令:includepagetaglibTaglib指令已经在上一节中讲述了。

Jsp.directive.page元素定义了一些页面所依赖的属性,这些属性的设置会被传递给容器。这个元素必须作为root元素的子元素出现在文档中。语法如下:

<jsp:directive.page page_directive_attr_list />

其中page_directive_attr_list表示了在<@ page …>可以出现的页面属性,这在第4章已经介绍过了。所有这些元素都是可选的。除了importpageEncoding属性外,其它属性都只能出现一次,但每个元素可以指定多个属性。

下面是一个指定错误页面的示例,告诉容器如果在执行时发生错误的话将转身到哪个页面:

<books xmlns:jsp="http://java.sun.com/JSP/Page">

  <jsp:directive.page errorPage="errorpage.jsp" />

  ...

</books>

Jsp:directive.include元素用于插入将另一个文件(可以是静态内容也可以是另一个JSP页面)内容插入到当前位置。可以在文档中的任何位置使用该指令:

<jsp:directive.include file="relativeURLspec" />

JSP文档在显示到客户时将不包含有include标签,取而代之的是会将被包含的文件内容取出放在该位置。

例如,如果希望在books.jspx文档显示出相关的杂志内容,可以使用包含指令将magazines.jspx的内容包含进来,如:

<jsp:root version="2.0" >

  <books ...>

  ...

  </books>

  <jsp:directive.include file="magazine.jspx" />

</jsp:root>

注意,此时是需要页面文档使用root元素,否则将会出现两个根元素:一个books,另一个是magazine。这样一来,文档在输出时将包含一个XML文档序列,浏览器可能会拒绝处理这样的数据,但此时的JSP文档仍然是合法的。

除了可以在JSP文档中包含另一个文档外,也可在文档中包含一个使用标准语法编写的JSP页面,也可以在使用标准语法编写的JSP页面中包含某个JSP文档。容器将会根据不同的情况进行自动的转换。

 

创建静态或动态内容

本节讲述如何在JSP文档中显示静态或动态的内容。静态内容可以使用未定义的标签或使用jsp:text元素来表示。Jsp:text标签会将其内容直接输出。

如果不使用jsp:text,在输出静态内容时,所有的空白字符将会被移除,例如:

<books>

  <book>

    Web Servers for Fun and Profit

  </book>

</books>

输出后的结果为:

<books><book>  

    Web Servers for Fun and Profit

</book></books>

如果使用jsp:text将输出内容包起来,空白字符将会被保留下来,输出时将会被替换为相应的转义字符。

使用jsp:text还可以输出一些不能很好地进行XML格式化的文本。例如,下例中的表达式${counter}如果不使用jsp:text标签的话,那这个文档就不是一个合法的JSP文档。

<c:forEach var="counter" begin="1" end="${3}">

  <jsp:text>${counter}</jsp:text>

</c:forEach>

jsp:text标签中不可以嵌套其它标签,所以如果希望在jsp:text中输入与标签同名的文本的话,必须使用CDATA进行转换。

在有些时间输出一些不太合法的标签内容时也需要使用CDATA进行包装,例如,下例中的blockquote标签,因为它与其它标签交叉在一起,所以必须使用CDATA

<c:forEach var="i" begin="1" end="${x}">

  <![CDATA[<blockquote>]]>

</c:forEach>

...

<c:forEach var="i" begin="1" end="${x}">

  <![CDATA[</blockquote>]]>

</c:forEach>

 

JSP页面一样,在JSP文档也可以使用动态内容,包括EL表达式、脚本元素、标准动作、自定义标签等。Books.jspx中就使用了EL表达式与自定义标签输出书籍的数据。

如下面这个片断中,使用JSTL中的foreach标签进行循环,并使用EL表达式输出JavaBean中的数据:

<c:forEach var="book" begin="0" items="${bookDB.books}">

  <book id="${book.bookId}" >

    <surname>${book.surname}</surname>

    <firstname>${book.firstName}</firstname>

    <title>${book.title}</title>

    <price>${book.price}</price>

    <year>${book.year}</year>

    <description>${book.description}</description>

    <inventory>${book.inventory}</inventory>

  </book>

</c:forEach>

在使用EL表达式时,必须注意有些运算符需要进行替换。下表列出了需要替换的运算符:

EL运算符

替换为

Lt

Gt

<=

Le

>=

Ge

!=

ne

使用EL表达式结合jsp:element还可以动态产生标签,例如下例中,动态生成了一个带有一个lang属性的header标签。

<jsp:element name="${content.headerName}"

    xmlns:jsp="http://java.sun.com/JSP/Page">

  <jsp:attribute name="lang">${content.lang}</jsp:attribute>

  <jsp:body>${content.body}</jsp:body>

</jsp:element>

其中,name属性指定了产生标签的名称。jsp:attribute用于生成lang属性,其标签体是lang属性的值。Jsp:body用于输出生成的标签体内容。上例中自动生成类似如下的标签:

<h1 lang="fr">Heading in French</h1>

JSP文档中的脚本需要使用脚本元素来编写。只有脚本表达式列表,在JSP页面中使用<%=expr %>编写的脚本表达式,在JSP文档应写成%=expr %的格式。

三种脚本元素分别是:声明、脚本、表达式。

jsp:declaration标签用于在文档中声明JAVA变量,格式如下:

<jsp:declaration> declaration goes here </jsp:declaration>

jsp:scriptlet标签用于在JSP文档中编写脚本,格式如下:

<jsp:scriptlet> code fragment goes here </jsp:scriptlet>

jsp:expression标签用于编写脚本表达式,表达式将会被求值计算,并将结果转换为字符串插入到输出流中。格式如下:

<jsp:expression> expression goes here </jsp:expression>

 

Jsp:root标签

Jsp:root标签用于表达式文档中的根元素。Jsp:root标签并不是必需的,你也可以使用自己的标签作为文档的根元素,例如在books.jspx中使用books作为文档的根元素。

虽然jsp:root标签不是必须的,但在下列情况下还是比较有用的:

l       当希望标明本文档是JSP文档,而又无需在部署描述符中注明,也不使用jspx作为文档扩展名时

l       当需要混合输出多个XML内容时

Versionjsp:root标签的唯一一个必需的属性,用于指定其符合的JSP版本。

Jsp:root还可以使用xmlns指定页面中使用的标签库。

示例中的books.jspx无需指定jsp:root标签,但假如需要在页面中混合输出其它的内容(如杂志列表),此时就需要使用jsp:root标签了。如:

<jsp:root   xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0" >

  <books>...</books>

  <magazines>...</magazines>

</jsp:root>

注意在上例中jsp:root标签中定义的jsp前缀,可以被用于booksmagazines中。

 

Jsp:output标签

Jsp:output标签用于在JSP文档输出时指定输出内容的XML声明以及文档类型的声明。

使用jsp:output标签指定的文档声明不会被容器处理,事实上,容器将直接将其输出到客户端。

例如,下面的声明:

<jsp:output doctype-root-element="books"          doctype-system="books.dtd" />

在输出到客户将变为:

<!DOCTYPE books SYSTEM "books.dtd" >

使用jsp:output指定文档类型并不会引发容器对文档的验证。

如果希望文档能够依据DTD进行验证,必须手动加入文档类型,就像普通XML文档一样。

下表中列出了jsp:output的属性。所有属性都是可选的,但有些属性依赖于其它的属性。本节余下的部分将详细介绍如何使用jsp:output产生XML声明与文档类型声明。

属性

用途

Omit-xml-declaration

设为trueyes忽略XML声明。设为falseno生成XML声明

Doctype-root-element

指出在DOCTYPE中的文档根元素。必须与doctype-system联合使用

Doctype-system

指定生成DOCTYPE并提供SYSTEM字符

Doctype-public

指定生成DOCTYPE的公用ID,必须与doctype-system联合使用

生成XML声明

下面是一个XML声明的示例:

<?xml version="1.0" encoding="UTF-8" ?>

这是一个默认的XML声明。默认情况下,JSP容器将产生一个这样的XML声明。XML声明并不是必须的,事实上,如果JSP文档不处理XML输出,它将不会包含XML声明。

在下列情况下,容器将不会包含XML声明:

l       设置了omit-xml-declaration属性为trueyes

l       在文档中使用了jsp:root标签,并且并未指定omit-xml-declarationflase

在以下情况下,容器将包含XML声明:

l       设置omit-xml-declaration属性为falseno

l       未使用jsp:root元素,并且示指定omit-xml-declaration属性

books.jspx页面中,并未指定jsp:rootjsp:output,但在输出的内容中将包含有XML声明。

 

生成文档类型声明

文档类型声明(DTD)定义了XML文档中的一些规则。XML文档并不是必须使用DTD,实现上,books示例并未使用DTD

本节将会讲解如何使用jsp:outputbooks.jspx加上DTD。也会讲述如何手动添加DTD,以及容器可以验证语法。

Jsp:output具有三个与DTD相关的属性:

l       Doctype-root-element:指定XML文档的根元素

l       Doctype-system:指定引用的DTDURI

l       Doctype-public:一种更加灵活的引用DTD的方式。该属性允许指定更多的DTD相关的信息。

使用这些属性的规则如下:

l       Doctype属性可以以任何顺序出现

l       如果doctype-system属性被指定,Doctype-root属性必须指定

l       Doctype-public必须没有指定,除非doctype-system被指定

下面的语法总结了其用法:

<jsp:output (omit-xmldeclaration=

  "yes"|"no"|"true"|"false"){doctypeDecl} />

doctypeDecl:=  (doctype-root-element="rootElement"

    doctype-public="PublicLiteral"

  doctype-system="SystemLiteral")

  | (doctype-root-element="rootElement"

  doctype-system="SystemLiteral")

假如希望一个名为books.DTDDTD,在DTD应该看起来如下:

<!ELEMENT books (book+) >

<!ELEMENT book (surname, firstname, title, price, year,

            description, inventory) >

<!ATTLIST book id CDATA #REQUIRED >

<!ELEMENT surname (#PCDATA) >

<!ELEMENT firstname (#PCDATA) >

<!ELEMENT title (#PCDATA) >

<!ELEMENT price (#PCDATA) >

<!ELEMENT year (#PCDATA) >

<!ELEMENT description (#PCDATA) >

<!ELEMENT inventory (#PCDATA) >

books.jspx中应该指定如下:

<jsp:output doctype-root-element="books" doctype-system="books.DTD" />

此时,窗口将生产如下的文档类型声明:

<!DOCTYPE books   SYSTEM "books.DTD" />

Jsp:output不需要放在页面上顶部,容器在生成文档类型说明时会自动放置在所有内容输出之前。

注意,容器并不会对文档按照所引用的DTD进行验证。它仅仅生成文档类型说明。

为了使容器能够验证JSP文档,你必须在页面中手动指定文档说明。然而,你必须在DTD中定义你所使用的所有标签,包括标准标签与自定义标签,例如jsp:useBeanc:forEach等。你还包含将DTD放置在<JavaEE_HOME>/domains/domain1/config目录下,这样JSP容器才能够对文档进行验证。

 

容器对JSP文档的识别

如果希望一个文件能够被容器当作是JSP文档,可以有如下三种办法:

l       web.xml文件中,在页面组中设置is-xml

l       使用Java Servlet 2.4版本的web.xml文件,并且文档使用jspx作为扩展名

l       在文档中使用jsp:root标签,这个方法可以对JSP1.2向后兼容

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值