`
canofy
  • 浏览: 830100 次
  • 性别: Icon_minigender_1
  • 来自: 北京、四川
社区版块
存档分类
最新评论

jstl知识

    博客分类:
  • j2EE
阅读更多

 

引用
作者: Hans Bergsten

http://blog.csdn.net/zt2oo8/
期待已久的日子即将到来: 最新版JavaServer Pages (JSP)2.0规范即将和其他的J2EE 1.4一同发布。新的JSP版本有一个新的飞跃,采用了新的方式:由于新的语言表达式(Expression Language,以下简称为EL)和JSP标准标签库(JSP Standard Tag Library ,以下简称为JSTL)这两种新的方式,在页面中不需要用java,对于开发一般的应用来说,重用代码变得更加容易。更具体来说,JSP 2.0带来了以下的优点:

 

首次被JSTL 1.0引入的EL现在被合并到JSP规范中,就像应用template text一样地使用所有的标准的和定制的组件。
新的EL已经被扩展,具备一个函数调用机制,JSTL1.1整合了一系列经常需要使用的函数。
新增加的变量和servlet 规范定义的错误处理机制被更好地组织起来。通过新增加的变量,JSP error pages 现在可以提供更多的错误信息。
容器因为更加严格的语法检查可以更容易地找出发生的错误。
所有的J2EE 1.4规范(包括JSP 2.0 和 Servlet 2.4),为了声明部署的规则描述而应用了XML schema。这样的好处之一是你现在可以通过任何顺序列出web.xml文件中的描述。JSP 2.0也增加了一些新的配置选项用于部署描述,允许通过全局的配置来代替基于每页的配置。
由于更具伸缩性的规则和新的自定义action element,现在就像编写XML文件一样,编写JSP页面变得更加容易。
定制的标签库现在可以开发成一系列的标签文件(具有JSP元素的文本文件),标签处理器可以使用新的、简化的标签处理器的API。与此同时,新规范加入了一些新的特性,比如:支持在jsp页面上显示动态属性列表和可执行片断属性。
在众多的书籍中,这是头一个讲解JSP 2.0新特性的文章。在这一部分,我们将看到和EL相关的信息,其他的新特性留到后面。在这里我假定读者已经熟悉JSP 1.2,而且至少听说过JSTL。

你可能对这本第三版的《JavaServer Pages》感兴趣。这本书中,我尽可能在细节上讲述所有的内容,而且并不认为你对JSP或者JSTL了解一切。这本书预计在2003年12月 出版,但是你现在可以在http://www.amazon.com、Barnes&Noble,或者其他在线书店预订。

EL(The Expression Language)

如果过去使用过JSTL,那么你可能已经熟悉了EL。EL在JSTL 1.0规范中被引入,用来在运行期间对Java表达式中action element属性赋值提供另一种选择。当JSTL EL已经非常迅速的流行起来情况下,还是存在一个问题: JSTL EL 表达式仅仅可以与JSTL和custom action一起使用,怎样才能使用非标准API对EL表达式求值?

JSP 2.0中,JSP容器自己可以理解EL表达式。这使你在所有过去只能应用Java表达式的地方应用EL表达式成为可能,比如:标准和定制action的属性值,模板文本。

在我们看具体的例子前,让我们更进一步的看看什么是EL。EL是从JavaScript中获得启发的一种语言,XPath(一种用来访问XML文档的语言),但是EL在对变量的null值和执行更多数据类型的自动类型转换的处理上更加宽松。这些新特性对于web应用非常重要,在这些应用中输入通常通过html表单的request parameter来得到。这些参数可能仅仅在某些请求下才能体现出来,而且浏览器经常将request parameter作为文本发送,然而应用程序经常需要把他们作为数字类型、布尔类型(true 或者 false)来使用。通过EL,你根本就很少需要关心缺少某些参数的值或者类型转换。

一个EL表达式包含变量和操作符。任何存储在某个JSP作用范围(如:page、 request、session、application)的bean能被作为一个EL变量来使用。另外,EL支持以下预定义的变量:

变量名称
说明

pageScope
一个包含所有page scope范围的变量集合 (a java.util.Map)

requestScope
一个包含所有request scope范围的变量集合 (a java.util.Map)

sessionScope
一个包含所有session scope范围的变量集合 (a java.util.Map)

applicationScope
一个包含所有application scope范围的变量集合 (a java.util.Map)

param
一个包含所有请求参数的集合 (a java.util.Map),通过每个参数对应一个String值的方式赋值

paramValues
一个包含所有请求参数的集合 (a java.util.Map),通过每个参数对应一个String数组的方式赋值

header
一个包含所有请求的头信息的集合, (a java.util.Map) ,通过每个头信息对应一个String值的方式赋值

headerValues
一个包含所有请求的头信息的集合 (a java.util.Map) ,通过每个头信息的值都保存在一个String数组的方式赋值

cookie
一个包含所有请求的 cookie集合 (a java.util.Map), 通过每一个cookie(javax.servlet.http.Cookie)对应一个cookie值的方式赋值

initParam
一个包含所有应用程序初始化参数的集合(a java.util.Map) ,通过每个参数分别对应一个String值的方式赋值

pageContext
一个javax.servlet.jsp.PageContext类的实例, 用来提供访问不同的请求数据

操作符描述了你对变量所期望的操作。如果你之前曾经使用过任何编程语言的话,在EL表达式中所使用的操作符对你来说可能看起来很熟悉。因为它们和那些在大多数语言中所支持的操作符一样。

Operator
Description

.
访问一个bean属性或者 Map entry

[]
访问一个数组或者链表元素

()
对子表达式分组,用来改变赋值顺序

? :
条件语句,比如: 条件 ? ifTrue : ifFalse.如果条件为真,表达式值为前者,反之为后者

+
数学运算符,加操作

-
数学运算符,减操作或者对一个值取反

*
数学运算符,乘操作

/ or div
数学运算符,除操作

% or mod
数学运算符,模操作(取余)

== or eq
逻辑运算符,判断符号左右两端是否相等,如果相等返回true,否则返回false

!= or ne
逻辑运算符,判断符号左右两端是否不相等,如果不相等返回true,否则返回false

< or lt
逻辑运算符,判断符号左边是否小于右边,如果小于返回true,否则返回false

> or gt
逻辑运算符,判断符号左边是否大于右边,如果大于返回true,否则返回false

<= or le
逻辑运算符,判断符号左边是否小于或者等于右边,如果小于或者等于返回true,否则返回false

>= or ge
逻辑运算符,判断符号左边是否大于或者等于右边,如果大于或者等于返回true,否则返回false

&& or and
逻辑运算符,与操作赋。如果左右两边同为true返回true,否则返回false

|| or or
逻辑运算符,或操作赋。如果左右两边有任何一边为true返回true,否则返回false

! or not
逻辑运算符,非操作赋。如果对true取运算返回false,否则返回true

empty
用来对一个空变量值进行判断: null、一个空String、空数组、 空Map、没有条目的Collection集合

func(args)
调用方法, func是方法名,args是参数,可以没有,或者有一个、多个参数.参数间用逗号隔开

一个EL表达式可以包含:数字、文本(在单引号或者双引号之间)、布尔值、null值。

因为一个EL表达式可以出现在静态文本出现的地方,因此你必须告诉JSP容器它应该被当作一个EL表达式来处理。你可以通过使用定界符来做到这一点。一个EL表达式总是以”${ }”来标记(一个“$”符号和一个左花括号,右花括号)。这里有一个EL表达式,它将一个命名为amount的变量加5:

${amount + 5}

如果你想要将5加到一个bean的property上,可以使用property访问操作符:

${order.amount + 5}

在当前这个指定的bean或者collection集合中,Property访问操作符(一个“.“符号)告诉EL去寻找名字为amount的property。

${order['amount'] + 5}

在[]之间的值必须是一个property的名字(就像上面的例子中那样)或者是一个保存property名字的变量(或者是一个完整的EL子表达式)。

EL表达式可以被用来赋值给任何标准的或者定制的JSP行为属性(action attribute),这些行为属性被标记为可以接受动态值(或者请求期间的属性值,就象它被正式调用一样):

<c:out value="${order.amount + 5}"/>

在JSP 2.0之前,你不得不使用Java表达式去给一个属性动态赋值。在过去的很多年中,这已经成为语法混乱的一个普遍根源。

最后,EL表达式可以在页面中和模板直接混合使用。当你生成HTML并且需要设置一个动态值给一个属性的时候,这非常方便:

<input name="firstName" value="${customer.firstName}">

JSP 1.2中,你不得不使用JSTL的<c:out>来实现同样的事情,最后把各种不同类型的元素混合起来,这导致程序理解起来非常的困难:

<input name="firstName"

value="<c:out value="${customer.firstName}"/>" >

新JSTL 1.1 Tag Library 标识符
JSTL1.1发布的是一个初级的版本,主要目的是用来整合JSTL和JSP2.0 。最明显的变化是JSTL1.0 “孪生函数库”(一组库用来接受EL表达式,另外一组用来接受JAVA表达式),而它们已经被一组既可以用于EL表达式也可以用于JAVA表达式的函数库所代替。

在JSTL 1.1中使用以下标识符:


URI
前缀

Core
http://java.sun.com/jsp/jstl/core
c

XML processing
http://java.sun.com/jsp/jstl/xml
x

I18N formatting
http://java.sun.com/jsp/jstl/fmt
fmt

Database access
http://java.sun.com/jsp/jstl/sql
sql

Functions
http://java.sun.com/jsp/jstl/functions
fn

如果你曾经使用过JSTL1.0,你可能会注意到新的标识符和旧的EL库标试符一模一样,除了加入了“/jsp path” element。你也可能注意到在JSTL1.1中有一个库,包含了EL的函数。我们稍后就会看到。

一个新的EL操作符
在JSP页面中一个非常普遍的需求就是:当某个条件为真时,要在网页中包含一些文字。在JSP1.2和JSTL1.1中,用具有代表性的<c:if>来实现,但是这样做非常繁琐。JSP2.0增加了一个新的条件操作符用于EL,以更加优雅的方式来处理这样的情况。这个条件操作符存在于很多编程语言中(比如:Java,C,JavaScript),因此你可能以前就见过它。它判断一个布尔的条件,当条件为真或者假时,分别取不同的结果。

一个能清楚说明它如何工作的例子:

 

代码
  1. <select name="artist">  
  2. <option value="1" ${param.artist == 1 ? 'selected' : ''}>  
  3. Vesica Pisces   
  4. <option value="2" ${param.artist == 2 ? 'selected' : ''}>  
  5. Cortical Control   
  6. <option value="3" ${param.artist == 3 ? 'selected' : ''}>  
  7. Vida Vierra   
  8. </select>   
<script>render_code();</script>
在这里,我使用了EL表达式和条件操作符来选择是否包含 html 中的 “selected”属性,只有符合条件的 “option” 才被添加 “selected” 属性。如果条件(param.artist==1)为真时,前面的“selected” 才被添加到网页中;否则就添加后面的(在这里是空字符串 ‘’)到页面中。

 

EL函数
当EL从JSTL规范中移到JSP规范中,它使用了一个如何进行函数调用的技巧。这个EL函数语法非常简单:方法名,紧接着在圆括号中有一组参数:

<%@ taglib prefix="fn"
uri="http://java.sun.com/jsp/jstl/functions" %>
${fn:length(myCollection)}
这是一个属于标签库中的函数,并且函数名字在页面中所包含的前缀要指定taglib库。在这个例子中,我使用了前缀fn,这是JSTL function库默认的前缀。

标签库描述符(Tag Library Descriptor,TLD)将函数名称映射到一个由JAVA实现的静态方法中:

 

代码
  1. <function>  
  2. <description>  
  3. Returns the number of items in a collection or the number of characters in a string.   
  4. </description>  
  5. <name>length</name>  
  6. <function-class>  
  7. org.apache.taglibs.standard.functions.Functions   
  8. </function-class>  
  9. <function-signature>  
  10. int length(java.lang.Object)   
  11. </function-signature>  
  12. </function>   
<script>render_code();</script>
在这里最有趣的element是<function-signature>。它包含一个函数返回类型的声明,静态的方法的名字,在圆括号中声明该方法所有参数的类型(可以没有参数或者有多个,参数间用逗号间隔开)。返回值类型和参数类型必须是java的原始类型(Object)或者是其他合法类型。

 

这个静态方法 length()在Jakarta Taglibs标准库中用类似于下面的代码实现的:

 

代码
  1. public static int length(Object obj)   
  2. throws JspTagException {   
  3. if (obj == null)   
  4. return 0;   
  5. if (obj instanceof String)   
  6. return ((String)obj).length();   
  7. if (obj instanceof Collection)   
  8. return ((Collection)obj).size();   
  9. if (obj instanceof Map)   
  10. return ((Map)obj).size();    
  11. int count = 0;   
  12. if (obj instanceof Iterator) {   
  13. Iterator iter = (Iterator) obj;   
  14. count = 0;   
  15. while (iter.hasNext()) {   
  16. count++;   
  17. iter.next();   
  18. }   
  19. return count;   
  20. }   
  21. if (obj instanceof Enumeration) {   
  22. Enumeration enum = (Enumeration) obj;   
  23. count = 0;   
  24. while (enum.hasMoreElements()) {   
  25. count++;   
  26. enum.nextElement();   
  27. }   
  28. return count;   
  29. }   
  30. try {   
  31. count = Array.getLength(obj);   
  32. return count;   
  33. catch (IllegalArgumentException ex) {}   
  34. throw new JspTagException("Unsupported type"));   
  35. }  
<script>render_code();</script>
就像你所看到的,在那里没有什么出奇的地方。它是一个常规的静态方法,这个函数中通过对运行期中的参数类别的判断,找出参数的长度。

 

除了在这个方法中使用的length()方法,JSTL1.1标签库还包含了许多其它经常使用的函数:

函数
描述

fn:contains(string, substring)
如果参数string中包含参数substring,返回true

fn:containsIgnoreCase(string, substring)
如果参数string中包含参数substring(忽略大小写),返回true

fn:endsWith(string, suffix)
如果参数 string 以参数suffix结尾,返回true

fn:escapeXml(string)
将有特殊意义的XML (和HTML)转换为对应的XML character entity code,并返回

fn:indexOf(string, substring)
返回参数substring在参数string中第一次出现的位置

fn:join(array, separator)
将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。

fn:length(item)
返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。如果是String类型,返回值是String中的字符数。

fn:replace(string, before, after)
返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果

fn:split(string, separator)
返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素

fn:startsWith(string, prefix)
如果参数string以参数prefix开头,返回true

fn:substring(string, begin, end)
返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符

fn:substringAfter(string, substring)
返回参数substring在参数string中后面的那一部分字符串

fn:substringBefore(string, substring)
返回参数substring在参数string中前面的那一部分字符串

fn:toLowerCase(string)
将参数string所有的字符变为小写,并将其返回

fn:toUpperCase(string)
将参数string所有的字符变为大写,并将其返回

fn:trim(string)
去除参数string 首尾的空格,并将其返回

结束语:
在这篇文章中,我从EL讲到JSTL1.1规范、EL新特色和JSTL 1.1函数库。接下来的部分我将要告诉你:关于JSP error-page的改进和增强; jsp:id 属性带来的益处;新的配置属性描述符;JSP2.0如何使JSP操作XML变得更加容易;自定义标签库的新特性。

JSP 2.0: The New Deal, Part 2
by Hans Bergsten, author of JavaServer Pages, 3rd Edition,12/03/2003

这篇文章是讲述加入到JavaServer Pages (JSP) 2.0 规范中的特性的系列文章的第二部分。在前面的第一部分,我描述了新的EL表达式,但是还有更多的内容没有涉及。这一部分描述的是JavaServer Pages (JSP) 2.0 规范在错误处理机制和新的部署描述符特性方面的增强。我假设你熟悉JSP 1.2,而且至少听说过JSP Standard Tag Library (JSTL)。

JSP Error Pages
如果你曾经在JSP和servlet的错误处理中使用过JSP error page,并且想要显示或者记录违例信息(违例导致JSP error page 被调用),那么你就知道在JSP1.2中这并不是件轻松的事情。原因是当在servlets和JSP 页面中声明了一个errorPage,违例(exception)被作为一个request attribute传递,它们要使用不同的属性名称。只有被传递的违例通过JSP属性名称自动地显示在 JSP error page中(通过exception脚本变量和${pageContext.exception} EL 表达式)。

JSP 2.0通过将相同的属性名称转换为servlet规范中的javax.servlet.error.exception来修正了这个问题。更进一步说,一个新增的 命名为errorData的EL pageContext变量揭露了发生问题的其他信息。ErrorData属性是javax.servlet.jsp.ErrorData的一个实例。这个实例可以被 用来作为一个bean和以下的properties一同使用:

Property
Java 类型
描述

requestURI
String
发生请求失败的 URI

servletName
String
发生错误的servlet或者JSP页面的名称

statusCode
int
发生错误的状态码

throwable
Throwable
导致当前error page被调用的违例

这里有个JSP error page的例子。这个例子使用了上面提到的一些property:

 

代码
  1. <%@ page isErrorPage="true" contentType="text/html" %>  
  2. <%@ taglib prefix="log" uri="http://jakarta.apache.org/taglibs/log-1.0" %>  
  3.   
  4. Sorry, but things didn't work out as planned. I've logged as much as   
  5. I know about the problem, so rest assured that my master will look   
  6. into what's wrong as soon as he's sober.   
  7.   
  8. <jsp:useBean id="now" class="java.util.Date" />  
  9. <log:fatal>  
  10. -----   
  11. ${now}   
  12. Request that failed: ${pageContext.errorData.requestURI}   
  13. Status code: ${pageContext.errorData.statusCode}   
  14. Exception: ${pageContext.errorData.throwable}   
  15. -----   
  16. </log:fatal>  
<script>render_code();</script>这个页面使用Apache Jakarta Taglib项目中的 Log tag library来显示一些确定的信息并记录下了具体的细节。

 

你可以在web.xml文件中使用<error-page>来对servlet和JSP 页面声明这是一个error page:

 

代码
  1. ...   
  2. <error-page>  
  3.   <exception-type>java.lang.Throwable</exception-type>  
  4.   <location>/error.jsp</location>  
  5. </error-page>  
  6. <error-page>  
  7.   <exception-code>500</exception-code>  
  8.   <location>/error.jsp</location>  
  9. </error-page>  
  10. ...  
<script>render_code();</script>如果你需要在某些特殊的JSP页面中使用一个不同的error page,可以用“@page”设置errorPage属性来有选择性地覆盖web.xml中的声明。

 

JSP 语法错误的报告

在JSP 1.2 和 JSP 2.0之间,一个细微但是重要的区别是JSP 2.0需要JSP容器支持“jsp:id”特性,虽然在JSP 1.2中这仅仅是一个建议。作为一个JSP开发者,这对你意味着什么呢?对于JSTL和定制的标签库的语法错误,它意味着你可以更好地获得有用的错误信息。

下面讲述它是如何工作的。当JSP容器将JSP页面转换为可以执行的servlet class,容器着眼于这个页面中声明的所有标签库。如果标签库中的一个或者多个库包含了一个标签库验证器(Tag Library Validator,TLV),容器就会在接受这个JSP页面前给予TLV一个检验当前页面的机会。容器给予TLV一个当前页面的XML视图用以分析。XML视图就像名称暗示的那样,是当前页面的另外一种版本, 所有常规的JSP元素和template text已经被转换为一种结构良好的XML文档。这个XML视图对TLV来说是很容易解析的,用于确定所有的custom actions被正确地使用(比如:custom actions被正确的嵌套,互斥的属性是不能在同一个action element中一同使用的)。

这就是“jsp:id”的由来。容器在页面中给每一个custom action元素分配了一个ID,并且维护了一张在ID和元素位置(文件、行号、列号)的映射表。添加的“jsp:id”属性,在XML视图中ID值对应于所有的custom action 元素,这样TLV就可以读取它。如果TLV发现了一个语法错误,它就会在返回给容器的错误信息中包含“jsp:id”属性值来确定当前无效的action element。这时容器使用映射,并添加发生错误的custom action element位置信息,提示给你。这使得开发人员找到并改正错误变得轻而易举。

所有的JSTL库都要有TLV。我强烈建议为你自己编写的类库开发TLV,而且任何第三方类库的开发人员也应该这样做。

如果你对XML视图和TLV并不熟悉,我在2001年的介绍JSP 1.2的文章中有一个简要的介绍("JSP 1.2: Great News for the JSP Community")。

JSP 部署描述符
JSP 2.0在web.xml文件中使用了servlet规范中定义的部署描述符的文件格式,就像早期的JSP规范中的那样。然而在JSP 2.0中有两个重要的变化:1、现在web.xml文件的格式是通过XML Schema定义的;2、为了最大限度地减少servlet和JSP规范之间的耦合度,大多数的JSP配置细节已经被移到一个新的XML element中。

XML Schema是一种用来描述XML文档语法规则的XML语言(可以定义XML element之间是如何嵌套的;一个element可以获得什么样的值; 值的唯一性的需求等等)。这是一个复杂的规范,但是幸运的是你不用为了写web.xml文件而需要明白XML Schema语法规则。因为servlet和JSP规范提供了易于理解的图表( JavaServer Pages, 3rd Edition书中包含了许多简单易懂的图表)。如果你还是想要更进一步了解XML Schema,请浏览W3C(http://www.w3c.org)的网站。

用XML Schema代替上一版本中的 Document Type Definition(DTD) 语言来声明XML文档结构的主要优点是:XML Schema具有更加富有表达能力,因此在解析web.xml文件的过程中能发现更多的错误,有希望解决在JSP容器之间更好地移植这个问题。

另外一个优点是(我确定你会感激于此的): 在web.xml文件中使用XML Schema可以使顶层的element按照任何顺序排列变得轻而易举。举例来说,在servlet和JSP 规范的上一个版本中,如果将<error-page> element 放到<welcome-file-list> element 前面,你将得到一个错误提示。在新版本的规范中,这样做就不会有问题。在顶层元素中的element的顺序尽管还必须要按照严格的顺序放置,但是在顶层元素以外至少你现在可以自由地支配了。

除了<jsp-file>要嵌套在<servlet>中,其它的element现在都被归组到一个新的顶层element中,这个element命名为<jsp-config>。在<jsp-config>中,你可以使用<taglib> element,和在JSP 1.2中具有相同的语法和含义,尽管它们并不需要实现了JSP 1.2 或者后续版本的容器,因为它们可以自动地从已经部署的JAR文件中获得标签库的定义。

新添加的<jsp-property-group>子元素更加有趣。你可以用它来配置一组匹配某个指定的URL的JSP页面。比如:

 

代码
  1. ...   
  2. <jsp-config>  
  3.   <jsp-property-group>  
  4.     <url-pattern>*.jsp</url-pattern>  
  5.     <scripting-invalid>true</scripting-invalid>  
  6.   </jsp-property-group>  
  7. </jsp-config>  
  8. ...  
<script>render_code();</script><url-pattern>元素确定这组JSP 页面应用哪一个配置。其他被嵌套的元素定义配置选项。这个例子中, <scripting-invalid>使应用JSP scripting elements (Java code) 在所有的JSP 页面中无效。

 

总地来说同<scripting-invalid>一样,你可以在<jsp-property-group>中使用以下的配置元素:

Element
描述

<el-ignored>
如果设置为true, 在匹配指定的URL模式的JSP 页面中,EL 表达式被当作常规的文本而不是EL 表达式。当移植看起来有EL表达式文本的JSP 1.2页面到JSP 2.0的时候,这非常有用。在已经转换为JSP 2.0的页面中,你可以使用一个新增的“elIgnoredpage”属性来选择EL是否有效

<scripting-invalid>
如果设置为true, 在某个匹配的JSP页面使用脚本

<page-encoding>
为匹配指定的URL模式的JSP页面指定编码。这是一个可选的配置(在每一个JSP页面中指定页面的编码),并且对于JSP页面来说这是使用某些文件编码(比如:EBCDIC)唯一的办法

<include-coda>
为所有匹配指定的URL模式的JSP页面的末尾自动包含一个文件,而指定相关的context路径。你可以在一个<jsp-property-group>中多次使用,或者通过多个<jsp-property-group>来实现

<include-prelude>
为所有匹配指定的URL模式的JSP页面的开头自动包含一个文件,而指定相关的context路径。你可以在一个<jsp-property-group>中多次使用,或者通过多个<jsp-property-group>来实现

<is-xml>
如果设置为true, 所有匹配指定的URL模式的JSP页面使用JSP XML语法(它们是JSP Document)

总结
在这部分,我讲述了JSP 2.0增强的错误处理机制和新的部署描述符的特性。在这个系列文章中,接下来的部分将涉及到JSP 2.0是如何使JSP操作XML变得轻松,还有与定制标签库相关的新特性。

JSP 2.0: The New Deal, Part 3
by Hans Bergsten, author of JavaServer Pages, 3rd Edition
04/21/2004

更具伸缩性的JSP Document格式规则
JSP 2.0 规范支持两种类型的JSP页面:一种是包含任何数据类型的常规JSP页面;另一种是具备良好结构的XML文档(具有XHTML和JSP元素)。为了做到这一点,在一个JSP Document中JSP的 “directive” 和 “脚本”必须用一种与常规的JSP页面不同的语法来编写:

常规的 JSP 页面
JSP 文档

 

代码
  1. <%@ page attribute list %>  
  2. <jsp:directive.pageattribute list />  
  3.   
  4. <%@ include file="path" %>  
  5. <jsp:directive.include file="path" />  
  6.   
  7. <%! declaration %>  
  8. <jsp:declaration>declaration</jsp:declaration>  
  9.   
  10. <%= expression %>  
  11. <jsp:expression>expression</jsp:expression>  
  12.   
  13. <% scriptlet %>  
  14. <jsp:scriptlet>scriptlet</jsp:scriptlet>  
<script>render_code();</script>

 

在一个JSP Document中,标签库作为XML名称空间被声明。比如:一个JSP Document 包含来自标准JSTL核心库中的XHTML模板文字和JSP action, 它应该有一个<html>根元素,有以下的名称空间的声明:

 

代码
  1. <html    
  2.   xmlns="http://www.w3c.org/1999/xhtml"    
  3.   xmlns:jsp="http://java.sun.com/JSP/Page"    
  4.   xmlns:c="http://java.sun.com/jsp/jstl/core"  
  5.   xml:lang="en" lang="en">  
<script>render_code();</script>xmlns属性为XHTML名称空间设置默认的名称空间,xmlns:jsp属性把jsp前缀和定义为JSP标准action的元素关联起来,并且xmlns:c属性将前缀“c”和JSTL核心库定义的元素关联起来。

 

JSP Document已经是JSP规范中的一部分了,但是起初是作为一个可选择的特性,并且后来还有许多的局限性。JSP 2.0解决了大多数局限性的问题,使XML和JSP协同工作变得更加简单。

首先对于JSP 2.0来说,一个JSP Document 必须要有一个<jsp:root>根元素用以告诉容器它是哪一种类型的JSP页面。JSP 2.0通过这种新的方式来标识一个JSP Document文件解决了这个限制。如果以下条件中有一个为true,这个文件就将被JSP 2.0容器作为一个JSP Document来处理:

请求的路径与在web.xml中声明的URL匹配, JSP property group 声明有一个 <is-xml>元素设置为 true。关于 JSP property group 声明在上一篇中有详细的说明。
请求路径的扩展名是.jspx,除非这个扩展名匹配一个JSP property group声明的URL pattern,而JSP property group声明<is-xml>元素为false。 换句话说,.jspx是默认的JSP Document的扩展名,但是它可以被一个property group的声明置为无效。
请求路径扩展名是.jsp或者匹配一个JSP property group声明的URL pattern,而且这个文件中的root element是<jsp:root>。
这些新的规则使采用一个常规的XHTML文件(用JSP element处理动态内容)的形式来编写JSP Document成为可能,比如:不需要将所有的内容都放到<jsp:root> element中。如果类似下面的例子那样创建一个JSP property group,你甚至可以用扩展名为.html的文件:

 

代码
  1. ...   
  2. <jsp-config>  
  3.   <jsp-property-group>  
  4.     <url-pattern>*.html</url-pattern>  
  5.     <is-xml>true</is-xml>  
  6.   </jsp-property-group>  
  7. </jsp-config>  
  8. ...  
<script>render_code();</script>用新的方法来生成XML Element
如果你曾经尝试用JSP1.2来编写JSP Document,那么你很可能在给XML element的attribute动态赋值时陷入了麻烦之中。比如,你想要给一个XML element的 class attribute赋值为一个用来保存用户风格样式参数的bean property。你首先可能试图像下面这样做:

 

<table class="%= user.getTableClass() %">
这样类型的Java 表达式,在一个JSP Document中能被用来作为一个 JSP action element的属性值。但是在template text中,JSP不会识别这样的语法,因此在这里是不会工作的。

用一个JSP action element来设置attribute的值,同样不可以:

<table class="<c:out value="${user.tableClass}" />">

这是因为在一个element attribute中一个格式完整的XML 文档不可以有一个“<”符号。

在JSP 1.2中,唯一动态设置一个element attribute 值的方法是使用令人生厌的CDATA 片断,将开始和结束的element当作原始文本(被动态生成的值包装)来处理:

<jsp:text><!CDATA[<table class="]]></jsp:text>
<c:out value="${user.tableClass}" />
<jsp:text><!CDATA[">]]></jsp:text>
JSP 2.0对于这种情况提供了两种简单的可选方案:1、在template text中使用一个EL表达式;2、使用一组新的标准的action element生成element。用EL表达式的例子如下:

<table class="${user.tableClass}">
一个JSP 2.0的容器对在template text中遇到的EL表达式求值,与在action 属性中一样。因此在大多数的情况下,这个解决方案是合适的。

如果你不能表示出你想要分配的值,你可以用三个新的标准action动态构造整个XML element,用JSP代码生成attribute的值。

 

代码
  1. <jsp:element name="table">  
  2.   <jsp:attribute name="class">  
  3.     <c:out value="${user.tableClass}" />  
  4.   </jsp:attribute>  
  5.   <jsp:body>  
  6.     ...   
  7.   </jsp:body>  
  8. </jsp:element>  
<script>render_code();</script>这个 <jsp:element> action 创建一个XML element,它的属性是由嵌套的<jsp:attribute> action 所创建的。这个属性的值被设置为<jsp:attribute>的运算结果,因此你可以使用自定义的action来产生它,比如:在这个例子中的<c:out> action。同样的element被设置为一个嵌套的<jsp:body>的运算结果。

 

一个用来声明XML的新的标准Action
一个XML document应该在文档的起始位置有一个XML的声明,可能跟随着一个DOCTYPE的声明。在JSP 2.0中,你可以用新增的<jsp:output>标准 action来生成这两个声明。

除非这个JSP Document有一个<jsp:root> element,就像它的root element(或者一个标签文件,标签文件我将在下一篇文章中讲述),JSP容器默认创建一个XML声明,就像这样:

<? xml version="1.0" encoding="encodingValue" ?>
encoding属性的值是字符编码,是由JSP页面的contentType属性决定的。如果你没有指定一个字符集,默认的就是UTF-8编码。如果你不希望生成一个XML的声明(因为这个JSP Document可能被包含在另外一个JSP页面中),你需要通过包含一个<jsp:output> action element来告诉JSP容器,就像这个JSP Document中那样:

<jsp:output omit-xml-declaration="true" />
用属性值true或者 yes来禁止生成这个声明。用false或者 no来允许生成这个声明。

一个DOCTYPE声明告诉一个XML parser(例如一个浏览器使用的parser)这个XML文档遵循了哪一个DTD(Document Type Declaration)。Parser可以用此信息来确认这个XML文档包含的仅是这个DTD声明的XML element。你不能在这个生成的JSP Documen中放置DOCTYPE声明(因为此时你正在表明这个 JSP Document和DTD一起编译),而是使用<jsp:output> action来告诉JSP容器为生成的结果添加一个声明:

 

代码
  1. <jsp:output doctype-root-element="html"  
  2.   doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"  
  3.   doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>  
<script>render_code();</script>
<jsp:directive.page contentType="text/html" />
就像这个例子一样,<jsp:output> action为XHTML给输出的结果添加了一个DOCTYPE声明:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
在这个例子中,我也包含了一个有contentType属性的<jsp:directive.page>声明,用来给输出的内容设置MIME类型为text/html,用来告诉浏览器如何对输出的内容进行处理。记住,因为XHTML特有的MIME类型实际是application/xhtml+xml,但是一些比较新的浏览器(特别是Internet Explorer 6)并不认识它,对于知道如何处理XHTML 1.0的大多数浏览器来说text/html才是一种允许接受的MIME类型。

结论
JSP2.0用XML document方式编写JSP页面更加容易,就像你已经在这部分看到的那样。最后一篇文章将要讲述和自定义标签库相关的新特性:新的标签文件格式和新的简单的标签API。
JSP 2.0: The New Deal, Part 4

byHans Bergsten, author of JavaServer Pages, 3rd Edition05/12/2004

在“JSP 2.0: 新特性”的最后一部分中,我们将要看两个新特性,它们使开发自定义标签库变得更加容易,它们是:标签文件和简化的tag-handler Java API。

以JSP Tag文件形式开发自定义Action

JSP试图让对Java没有经验的人写动态页面成为可能。在页面间,重用一部分动态的、复杂的内容到目前为止仍然是令人痛苦的事情。举例来说,你想要在一些页面中放置一个投票程序,包括问题和答案。在 JSP 2.0之前,你有三个选择:1、你可以拷贝并粘贴投票的程序到你希望添加的每一个页面中;2、一个稍好的选择是编写一个独立的JSP页面来生成投票的表单,并且在其他页面中用<jsp:include>或者 <c:import> action来包含这个独立的页面。但是你仅仅可以通过它来输入String类型的参数,不能是一个保存答案的bean或者一个Map。3、用一个Java tag handler类实现一个自定义action, 但是这需要建立在你对Java的了解基础上。

JSP 2.0增加了第四种选择:也就是用标签文件的形式开发自定义action。一个标签文件是一个纯文本文件,你对所有的动态生成的部分使用JSP element,就像在常规的JSP页面中那样。和一个Java 标签handler有同样目的,即:为自定义的action 提供逻辑运算。标签文件和JSP 页面之间主要的区别是一个标签文件有一个以.tag为扩展名的标签文件,用这个扩展名来区别jsp页面,并且你可以使用仅在标签文件中有效的一些新的标签来定义输入和输出。

更进一步来看,这里有一个标签文件“poll.tag”,它生成一个投票的表单:

 

代码
  1. <%@ tag body-content="empty" %<sp>
分享到:
评论

相关推荐

    jstl标签知识汇总

    ### JSTL标签库知识点详解 #### 一、概述 JSTL(JavaServer Pages Standard Tag Library)是一种标准标签库,旨在简化JavaServer Pages (JSP) 的开发工作。通过提供一组预定义的标签,JSTL使得开发者能够更加高效地...

    jstl.rar_JSTL_jsp-jstl

    在"jstl知识.pdf"中,可能会详细讲解如何引入JSTL库,如何配置web.xml,以及如何在JSP页面中使用各个标签库的标签。同时,教程可能会提供各种示例,如使用`&lt;c:set&gt;`设置变量,使用`&lt;c:out&gt;`输出变量,以及如何使用`...

    mybatis-3.2.5_JSTL_

    结合以上两个知识点,若在项目中同时使用MyBatis和JSTL,可能是在JSP页面上展示MyBatis查询到的数据,利用JSTL的标签进行数据的处理和展示。例如,可以使用`&lt;c:forEach&gt;`遍历查询结果,然后通过`&lt;fmt:formatDate&gt;`...

    jstl.pdf课程资源

    ### JSTL (JSP Standard Tag Library) 详解 #### JSTL 概述 JSTL(JSP Standard Tag ...以上内容详细介绍了JSTL的核心概念、版本差异、标签库类型以及EL表达式语言的使用方法,为读者提供了全面的JSTL知识体系。

    Jstl基本知识简介

    ### JSTL基本知识简介 #### 一、JSTL概述 JSTL(JavaServer Pages Standard Tag Library,JavaServer 页面标准标签库)是一个不断完善的开源JSP标签库,由Apache Jakarta项目组维护。该标签库的目标是简化JSP页面的...

    el&jstl.pdf

    ### EL与JSTL知识点详解 #### 一、EL (Expression Language) 概述 **1.1 什么是EL** EL(Expression Language),即表达式语言,是一种简单却功能强大的语言,专门设计用于访问和操纵JavaBean属性。EL提供了一种...

    java学习资料jstl

    Java是一种广泛使用的编程语言,尤其在企业级应用...这套"java学习资料jstl"提供了一系列源码实例,对于初学者来说,是掌握JSTL知识的好资源。通过仔细研究和实践,你将能够熟练运用JSTL,提升你的Java Web开发技能。

    我自己的jstl小型项目

    **JSTL 知识点详解** JSTL 是一个开源项目,由Apache软件基金会的Jakarta项目维护。它的主要目标是简化JSP开发,通过提供一系列预定义的标签,让开发者可以避免使用脚本语言(如Java)在页面上编写复杂的逻辑。以下...

    JAVA EE JSP_JSTL

    **JAVA EE JSP_JSTL 知识点详解** JAVA EE(Java Platform, Enterprise Edition)是Java平台的一个版本,主要用于构建分布式、多层的企业级应用。JSP(JavaServer Pages)是JAVA EE中的一个重要组成部分,它是一种...

    javaweb教程-java中级资料(ppt+txt).zip

    课件总共有18个章节 ...第二节 CSS 知识 第三节 JavaScript知识 第四节 Mysql知识 ...第十三节 JSTL知识1 第十四节 JSTL知识2 第十五节 监听器 第十六节 过滤器 第十七节 文件上传下载以及验证码 第十八节 JSP分页

    J2EE JSP-JSTL.ppt(787K)

    **J2EE JSP-JSTL 知识详解** **1. JSTL 简介** JSTL,全称 JavaServer Pages Standard Tag Library,是Java社区过程(JCP)制定的一个标准规格,旨在为Java Web开发人员提供一套通用的标准标签库。JSTL的出现是为了...

    EL表达式与JSTL

    ### EL表达式与JSTL知识点详解 #### 一、EL表达式简介 EL(Expression Language)表达式,又称表达式语言,是Java Server Pages (JSP) 中一个非常重要的特性。通过使用EL表达式,开发者能够更加简洁地访问变量和...

    jstl深入学习知识

    标签库JSTL(JSP Standard Tag Library): 因为在jsp中使用java代码去控制页面的显示(即:用小段的),可读性很差,这样后期维护会比较麻烦,所以引入了Java标签库。  常用的JSTL标签库:  核心标签库:...

    jstl1.1.jar和standard1.1.jar

    想起先前看到的一个知识点:tomcat 6 实现了 servlet 2.5 和JSP2.1的规范相应的 tomcat 5 实现的是 2.4和2.0,想到tomcat5不支持JSTL1.2,于是替换JSTL1.1的包试试看后,问题解决 解决方法:移出工程lib目录中的...

    jstl入门示例源码

    **JSTL(JavaServer Pages Standard Tag Library)** 是一个标准的标签库,它为JavaServer Pages (JSP) 提供了一系列的标签,用于简化网页开发。...因此,对于初学者来说,熟悉并掌握JSTL的基本知识至关重要。

    JSTL操作XML JSTL操作XML

    ### JSTL操作XML知识点详解 #### 一、引言 Java Server Pages Standard Tag Library (JSTL) 是一种标准的、基于XML的标签库,它简化了JSP页面的开发工作,使得开发者能够更加专注于业务逻辑而不是页面的布局与控制...

    EL与JSTL下载资料

    在"EL与JSTL下载资料"中,你可以找到关于这些知识点的详细讲解,包括概念介绍、实例演示、常见问题解答等,帮助你在Java Web开发中熟练掌握这两种技术,提升开发效率,编写出更清晰、更易于维护的代码。通过深入学习...

    简单的JSTL例子

    ### 知识点一:JavaServer Pages Standard Tag Library (JSTL) JSTL,即JavaServer Pages Standard Tag Library,是Java平台上的一个标准标签库,用于简化JSP页面的开发工作。它提供了一系列预定义的标签,可以执行...

    JSTL标签课件PPT

    本课件PPT将深入探讨JSTL的核心概念、基本用法以及实际应用中的关键知识点。 1. **JSTL概述** JSTL是由Apache软件基金会的Jakarta项目开发的,旨在替代硬编码在JSP页面上的Java脚本。它包括几个主要的标签库,如...

Global site tag (gtag.js) - Google Analytics