在JSP规范中定义了两种语法,用于编写JSP页面。一种是标准的JSP语法格式,在前面几节中介绍和使用的就是JSP语法格式,另一种是XML语法格式。使用标准语法的JSP文件叫做JSP页面,使用XML语法的JSP文件叫做JSP文档。
下面,我们通过两个例子来看看采用标准JSP语法格式和采用XML语法格式的区别。例12-13的greet.jsp使用标准的JSP语法格式编写,该页面向用户显示欢迎信息;例12-14的greet_xml.jsp完成相同的功能,不过是采用XML语法编写的。
例12-13 greet.jsp
① <%@ page contentType="text/html;charset=GB2312" %>
<html>
② <head><title>欢迎页面</title></head>
<body>
③ <%! String greeting="欢迎你!"; %>
④ <%
String user=request.getParameter("user");
StringBuffer sb=new StringBuffer();
sb.append(user);
sb.append(",");
sb.append(greeting);
%>
<center>
⑤ <h1>程序员之家留言板</h1>
⑥ <%=sb.toString()%>
</center>
</body>
</html>
例12-14 greet_xml.jsp
<?xml version="1.0" encoding="GB2312"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
① <jsp:directive.page contentType="text/html;charset=GB2312"/>
<html>
② <head><title>欢迎页面</title></head>
<body>
③ <jsp:declaration>String greeting="欢迎你!";</jsp:declaration>
④ <jsp:scriptlet>
String user=request.getParameter("user");
StringBuffer sb=new StringBuffer();
sb.append(user);
sb.append(",");
sb.append(greeting);
</jsp:scriptlet>
<center>
⑤ <h1><jsp:text>程序员之家留言板</jsp:text></h1>
⑥ <jsp:expression>sb.toString()</jsp:expression>
</center>
</body>
</html>
</jsp:root>
注意,在使用XML语法格式编写JSP文档时,一定要遵照XML格式良好的定义。JSP文档可以直接由JSP容器解释运行,容器会检查JSP文档是否是格式良好的、结构化的文档。
12.8.1 JSP文档的标识
采用XML语法格式编写JSP页面时,需要向容器表明这是一个JSP文档。有3种方式可以标识一个JSP文档。
? 在web.xml文件中,通过<jsp-property-group>元素的子元素<is-xml>(参见附录D的D.15节)来指明给出的文件是否是JSP文档。采用这种方式将覆盖其他的检测方式。如果没有采用这种方式,则采用下面的两种方式进行检测。
? 如果Web应用程序的web.xml文件遵照Servlet 2.4规范,而且文件的扩展名为.jspx,那么该文件就是JSP文档。否则
? 如果JSP页面的根元素为<jsp:root>,那么该文件被标识为JSP文档。这种方式提供了对JSP 1.2版本的向下兼容。
如果一个文件被标识为JSP文档,但不是格式良好、名称空间感知(namespace-aware)的XML文档,那么转换阶段就会报错。
12.8.2 JSP文档中的元素语法
JSP文档使用XML名称空间来标识标准的指令、脚本和动作元素,以及自定义的动作元素。JSP规范中定义的标准动作元素存在于http://java.sun.com/JSP/Page名称空间中,通常使用的名称空间前缀是jsp。如例12-14第3行的代码所示:
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
在JSP文档中,如果要使用JSP规范中的标准元素,那么必须声明http://java.sun.com/JSP/Page名称空间。
下面我们介绍一下在JSP文档中可以使用的元素。
1.<jsp:root>
<jsp:root>元素只能作为JSP文档的根元素使用,不过JSP文档也可以不使用<jsp:root>元素(JSP 1.2规范要求所有的JSP文档都以<jsp:root>作为它的根元素)。
<jsp:root>元素有两个作用,一个是用于标识JSP文件为JSP文档,另一个是用于包装非格式良好的XML文档。
<jsp:root>元素有一个必备的属性version,用于指明页面使用的JSP规范的版本,如例12-14第3行的代码所示:
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
此外,<jsp:root>元素还可以有0个或多个xmlns属性,用于声明名称空间。在JSP文档中,不能使用taglib指令,取而代之的是使用xmlns属性,形式为xmlns:prefix="uri",uri标识要使用的标签库。在JSP1.2规范中,要求所有的标签库声明都要在<jsp:root>元素上,而JSP2.0规范则没有这个要求,我们可以在使用标签时再声明。例如,我们要使用JSTL中的标签<c:forEach>(参见第17章),可以直接在<c:forEach>上声明使用的标签库,如下:
<c:forEach xmlns:c="http://java.sun.com/jsp/jstl/core"
var="counter" begin="1" end="${3}">
<row>${counter}</row>
</c:forEach>
2.<jsp:output>
<jsp:output>元素用于输出XML声明和文档类型声明,如果你使用JSP文档想要产生XML的输出,那么<jsp:output>元素将是非常有用的。
<jsp:output>元素的语法如下:
<jsp:output ( omit-xml-declaration="yes|no|true|false" ) { doctypeDecl } />
doctypeDecl ::= ( doctype-root-element="rootElement"
doctype-public="PubidLiteral"
doctype-system="SystemLiteral" )
| ( doctype-root-element="rootElement"
doctype-system="SystemLiteral" )
<jsp:output>元素有4个可选属性,如下所示。
? omit-xml-declaration
指示是否忽略输出XML声明。有效的值为“true”,“yes”,“false”和“no”。如果JSP文档中有<jsp:root>元素,那么该属性的默认值是“yes”;如果JSP文档中没有<jsp:root>元素,那么该属性的默认值是“no”。例如:
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<number>
<jsp:expression>2+3</jsp:expression>
</number>
</jsp:root>
将输出下面的XML文档:
<number>5</number>
而
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:output omit-xml-declaration="no"/>
<number>
<jsp:expression>2+3</jsp:expression>
</number>
</jsp:root>
或者JSP文档(文件扩展名为.jspx或者在web.xml文件中将<is-xml>元素设为true)
<number xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:expression>2+3</jsp:expression>
</number>
将输出下面的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<number>5</number>
输出的XML声明中的编码值是HTTP响应字符流的编码。
? doctype-root-element
指定在输出的文档类型声明中的XML文档根元素的名称。只有在指定了doctype-system属性时,才可以而且必须使用该属性。
? doctype-system
指定在输出的文档类型声明中的系统标识符。例如:
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:output omit-xml-declaration="no"
doctype-root-element="number"
doctype-system="number.dtd"/>
<number>
<jsp:expression>2+3</jsp:expression>
</number>
</jsp:root>
将输出下面的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE number SYSTEM "number.dtd">
<number>5</number>
? doctype-public
指定在输出的文档类型声明中的公共标识符。只有在指定了doctype-system属性时,才可以使用doctype-public属性。例如:
<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:output doctype-root-element="html"
doctype-public="-//W3C//DTD XHTML Basic 1.0//EN"
doctype-system="http://www.w3.org/TR/xhtml-basic/xhtml-basic10. dtd" />
<body>
<h1>Example XHTML Document</h1>
</body>
</html>
将输出下面的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml- basic/xhtml-basic10.dtd">
<html><body><h1>Example XHTML Document</h1></body></html>
提示:如果在JSP文档中没有指定响应内容的MIME类型和字符编码,那么默认情况下Tomcat将以text/xml类型和UTF-8编码向客户端发送响应。可以通过<jsp:directive.page>指令元素来指定响应内容的MIME类型和字符编码,如下:
<jsp:directive.page contentType="text/html;charset=GB2312"/>
3.指令与脚本元素
在JSP文档中可以使用page和include指令元素,它们的语法格式如下:
<jsp:directive.page attr1="value1" attr2="value2" …/>
<jsp:directive.include file="relativeURLspec"/>
page和include指令元素的属性在标准JSP语法和XML语法中都是相同的。在JSP文档中,不能使用taglib指令。
脚本元素包含三个部分:声明、脚本段和表达式,它们在JSP文档中的语法格式如下所示:
<jsp:declaration> declaration(s) </jsp:declaration>
<jsp:scriptlet> scriptlet </jsp:scriptlet>
<jsp:expression> expression </jsp:expression>
例如:
<jsp:declaration>int count=0;</jsp:declaration>
<jsp:scriptlet>count++;</jsp:scriptlet>
<jsp:expression>count</jsp:expression>
在JSP页面中,对于请求时的属性值表示,可以使用表达式语法<%= expr %>,例如:
<% String url="2.jsp"; %>
<jsp:include page="<%=url%>"/>
而在JSP文档中,则要使用%= expr %,例如:
<jsp:scriptlet>String url="2.jsp";</jsp:scriptlet>
<jsp:include page="%=url%"/>
不过要注意,在JSP文档中,这种语法仅仅适用于标准动作元素或者自定义的动作元素。例如,HTML中的<a>元素不是动作元素,语句
<a href="%=url%">2.jsp</a>
被转换后,仍然是
<a href="%=url%">2.jsp</a>
在JSP文档中,应该写为下面的形式:
<jsp:text><![CDATA[<a href="]]></jsp:text>
<jsp:expression>url</jsp:expression>
<jsp:text><![CDATA[">2.jsp</a>]]></jsp:text>
4.动作元素
动作元素的语法在JSP页面和JSP文档中是一致的,参看第12.3.3节。
5.文本与注释
在JSP文档中也可以直接书写要输出的文本或XML片段,不过在书写这些内容时要符合XML文档格式良好的约定。此外,还可以使用<jsp:text>元素来封装要输出的文本内容,该元素既可以用于输出固定的内容,也可以用于输出动态的内容。<jsp:text>元素的用法类似于XSLT中的<xsl:text>元素。
在JSP文档中,不能使用JSP注释,只能使用XML(HTML)类型的注释,即
<!-- comments … -->
这对于程序员来说是非常不方便的,JSP文档中没有注释的Java代码可能会让程序员不得不去回想先前所写代码的作用,而如果采用XML(HTML)类型的注释,又会在客户端暴露代码实现的细节。