分享
 
 
 

JSP标准标签库(二)

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

英文原文地址:http://www.onJava.com/pub/a/pub/a/onjava/2002/05/08/jstl.Html

本文是 JSTL 系列的第二篇-- jsp 标准标签库.相关资源:JSP Standard Tag Libraries, Part 1(http://www.onjava.com/pub/a/onjava/2002/03/13/jsp.html)

此文中,我们将更详细地讲述不同标记描述文件(Tag Library Descriptor,TLD)里的各种标记。我们会通过例子去说明条件、迭代、URL、SQL及XML等标记的使用。文章的目的就是展示JSTL的主要功能,说明如何使用JSTL以及说明如何使用JSTL去改善JSP的开发。

简单来说,JSTL就是一套可以用在多个方面的自定义功能,JAVA标准组织(Java Community Process,JCP)在JSR-52里面定义到,JSTL提供表达式语言(eXPression language),流程控制及数据检校等功能,JSTL规范的最后版本可以在JCP的网站上找得到。

JSTL要求运行在支持JSP 1.2版的服务器上,JSTL的主旨就是简化JSP的开发以及提供访问、操作数据的简便方式,使用JSTL可以使用大家的工作更轻松。

JSTL包含了多个TLD和JAR文件,这些TLD覆盖很多功能,我们将一个个说明。首先,我们要重点说一下JSTL最突出的功能,表达式语言。

实际上,表达式语言是由JSR-152专家组所提供的,也就是定义JSP 2.0的专家组。JSR-152和JSR-52很多时是在一起工作的,更甚的是,表达式语言已经成为JSP 2.0的一部分。表达式语言提供访问数据的一种简便方法,它支持运算,支持bean,支持集合,同时也支持类型转换和属性的缺省值。

使用表达式语言

表达式语言是通过 ${expression} 这样的形式来调用的,并且它只能用在属性里面,例如:

<c:if test="${prodUCt.price >= customer.limit}">

...

</c:if>

在上面的例子,我们使用表达式语言做一个比较运算,它也可以混合一些静态文本,就象下面的例子:

<c:forEach var="current">

<c:out value="Product-${current}"/>

</c:forEach>

在例子里面,我们枚举出一个集合里面的元素,之后将它加在一个字符串后面输出,结果就象:

Product-1

Product-2

Product-3...

从例子里可以看出,相对于以前的代码,使用JSTL之后,在整个过程变得简单清晰。在以前,你需要定义一个对象,要知道对象的类型,并且要掌握一些脚本语言,而这只是去完成一个简单的操作。

现在,有了JSTL,我们可以使用简单的语法去访问数据,表达式语言是非常适合做这样的工作的。

再举一个例子,我们可以将:

<jsp:useBean id="customer" type="sample.Customer" scope="request"/> ...

Customer Name: <%=customer.getName()%>

...

<% if (customer.getState().equals("CO")){ %>

...

<%}%>

转换成:

Customer Name: ${ customer. name}

<c:if test="${customer. state == param. state}">

...

</c:if>

表达式语言允许直接访问JSP中任何作用域的变量,比如可以用${foo}来代替pageContext.findAttributes("foo")。还有可以能过点或索引来访问bean以及它们的属性,如:

${user.address.city}

${products.[product.id]}

${products.["Part-010"]}

表达式语言提供所有你使用到的运算:==, !=, <,>, <=, >=, &&, , ! 。这表达式语言中,它们表示为lt, gt, le, ge, eq, ne,这样可以避免与XML的语法重复。表达式语言也有普通的算术运算同布尔运算。另外,表达式语言还具有自动类型转换的功能,如int value = "${request.myValue}"会自动转换。

在表达式语言是可以提供属性的缺省值的,使用缺省值是为了避免空指针异常,下面是一个例子,

<c:set var="city" value="${user.address.city}" default="N/A" />

现在,我们已经对表达式语言有所了解,下面,让我们看一下与EL相关的操作。

核心操作

在核心标记库里使用到表达式语言。<c:out>标记将表达式语言所计算出的值输出到当前的JSP输出流。这个与JSP中的<%= scripting exp %>相似。比如:

<c:out value="${customer.name}" default="N/A" />

核心标记库里还可以设置和清除变量。变量的缺省作用域是PAGE。例如我们可以用<c:set var="customer" value=${customer}" />设置一个页面变量customer,再用一个<c:remove var="customer" />去清除它。

现在,能过JSTL,我们可以使用一个标记去捕捉java.lang.Throwable,例如:<c:catch var="myError" />。使用这个标记,可以统一页面的异常处理,但这不意味着代替JSP的错误页面机制。通过使用<c:catch>标记,就可以在页面上控制特定的异常,而不用转到错误页面,其实并不是所有异常都需要转到错误页面。通过使用<c:catch>标记,与用户的交互也变得更友好。

条件操作

在条件操作中使用EL是简化JSP的一种强有力的手段。<c:if>标记,它可以构造简单的条件表达式。下面的例子,访问了一个对象的属性:

<c:if test="${user.visitCount == 1}"

Welcome back!

</c:if>

当然,有IF就一定会有ELSE。如果是"if/then/else"结构的,则使用<c:choose>, <c:when>和<c:otherwise>标记。

看一看下面的例子,我们对一个查询结果集做过了一些处理,之后使用标记去显示正确的信息。

<c:choose>

<c:when test="${count == 0}">

No records matched your selection.

</c:when>

<c:otherwise>

<c:out value="${count}"/> records matched your selection.

</c:otherwise>

</c:choose>

迭代操作

在整个JSTL里面,可能最有用的操作就是迭代操作了。迭代操作的标记有<c:forEach>,<c:forToken>和<x:forEach>。最后一个是XML的迭代操作。下面我们会说到XML的操作,但现在我们还是继续核心操作。

迭代操作支持所有的J2SE集合类型,包括List, LinkedList, ArrayList, Vector, Stack, 和Set。还有java.util.Map对象,如HashMap, Hashtable, Properties, Provider, 和Attributes。还有数组。当使用基本数据类型的数组时,它会包装成对应的基本类。在迭代操作中,会输出两个东西,当前的数据项和迭代的状态。看看下面的例子:

<table>

<c:forEach var="product"

items="${products}"

varStatus="status">

<tr>

<td><c:out value="${status.count}"/></td>

<td><c:out value="${product.name}"/></td>

</tr>

</c:forEach>

</table>

例子中,products是一个集合,当前的数据项入在变量product里面,变量status是当前的迭代状态。是不是很简单。

url操作

除了迭找操作外,核心标记库里也提供了URL相关的操作,它包括超链接,引入和重定向。可以使用<c:url>去设定一个URL。假如我们想指定一个带参数的URL,并在链接中使用,那就象下面的例子:

<c:url=http://mysite.com/register var="myUrl">

<c:param name="name" value="${param.name}"/>

</c:url>

<a href='<c:out value="${myUrl}"/>'>Register</a>

JSTL中有很强大的资源引入机制,它可以指定绝对的URL,在同一应用的相对的URL,不同应用的相对的URL,还有FTP资源。下面给出一些例子:

绝对URL:<c:import url="http://sample.com/Welcome.html"/>

同一应用中的相对的URL:<c:import url="/copyright.html"/>

不同应用中的相对的URL:<c:import url="/myLogo.html" context="/common"/>

FTP资源:<c:import url="ftp://ftp.sample.com/myFile"/>

通过上面的说明可以看出,<c:import>比<jsp:include>强大得多,但是,也有其它理由去使用<jsp:include>的。在JSTL中,对于引入的资源使用了缓存,但有时候缓存会是没用的。如果你使用<jsp:include>,资源的内容会被读入并写到当前的JspWriter,而且是每访问一次就重读一次。而使用<c:import>,资源的内容则只会读取一次。

本地化操作

JSTL的另一样重要功能就是本地化操作,通过当前请求的,或者环境配置中的参数,就可以简便地实现本地化操作。这个操作是使用J2SE中的ResourceBundle机制去存放各种译文的。JSTL通过设定的区域,去找到并使用相应的ResourceBundle。用<fmt:setLocale>去设置区域,如<fmt:setLocale value="es_Es"/>,value属性为语言代码和国家代码。也可以直接指定一个ResourceBundle:<fmt:bundle basename="ApplicationResource_fr"/>。

一旦设置了区域或者绑定特定的信息,那么<fmt:message>标记就会自动地选择正确的ResourceBundle,使用以下的形式就可以输出正确的信息:

<fmt:message key="welcome">

<fmt:param value="${visitCount}" />

<fmt:message/>

你也可以直接使用< fmt:requestEncoding/>标记去设置当前请求的字符集。

获取和显示文字信息只是本地化操作的一半,而另一半就是格式化同解释日期和数字,不同的地域会有不同的日期和数字格式的。使用<fmt:formatNumber>和<fmt:parseNumber>去格式化数字,金额,百分比数,而且还可以指定格式,就如<fmt:formatNumber value="12.3" pattern=".00"/>会输出"12.30"。

日期和时间的处理使用<fmt:formatDate>, <fmt:timeZone>, <fmt:setTimeZone>, 和 <fmt:parseDate>。

sql操作

SQL操作允许你直接操作数据源,在MVC模式里面是不提倡这样做的,我更是彻底反对在一个正式产品里这样做。它们只适用于快速开发,原型开发或者是一些小的应用里面,它们是不应该用在一些大型的应用上面的。不过也有许多开发人员想使用它,所以它保留在标准里面。下面我们来看一下SQL操作。

SQL标记可以用来设置数据源,执行查询,访问查询结果,执行更新等。所有的SQL操作都是基于某一数据源的。有几种方式可以设置数据源:在配置文件里设置

sql.datasource参数,在程序中直接设置,或者使用<sql:setDataSource>标记。如下面就设置了一个mysql的数据源:

<sql:setDataSource var="datasource" driver="org.gjt.mm.mysql.driver" url="jdbc:mysql://localhost/db" />

与JDBC中的DriverManager相似,<sql:setDataSource>也只是一个包装。数据源的属性,它可以是一个JNDI资源,也可以是一个JDBC参数。用<sql:query datasource="${datasource}" ... />这样的方式来访问数据。

我们把这些东西都放在一起,它是会是这样的:

<sql:query var="customer" datasource="${datasource}"

SELECT * FROM customers WHERE state = 'CO' ORDER BY city

</sql:query>

<table>

<c:forEach var="row" items="${customers.row}">

<tr>

<td><c:out value="${row.custName}" /></td>

<td><c:out value="${row.address}" /></td>

</tr>

</c:forEach>

</table>

使用事务和执行更新一样也很简单。例如,我们建立一个事务,并执行几个更新,那就是下面代码:

<sql:transaction dataSource="${dataSource}">

<sql:update>

UPDATE account SET Balance =Balance -? WHERE accountNo = ?

<sql:param value="${transferAmount}"/>

<sql:param value="${accountFrom}"/>

</sql:update>

</sql:transaction>

用<sql:dateParam>标记来设定SQL语句中的类型为日期型的参数的值。

xml操作

JSTL中最后一类操作是XML操作,XML操作也可细分成核心操作,流程控制操作和转换操作。JSTL中的XML操作是基于Xpath的,Xpath是XML操作专用的表达式语言。JSTL所有的XML操作中,用"select"属性去指定XPath表达式,这些信息将由XPath引擎解释。

XML核心操作与JSTL的核心操作相似,它包含<x:out>, <x:set>, 和<x:parse>标记。<x:parse>标记提供将XML文档转换成结构化数据的功能,之后,这些数据就能被XPath引擎解释了。例如,有一个关于书籍的XML文档,我们就可以解释它,并打印出来:

<c:import url="http://oreilly.com/book?id=1234" var="xml"/>

<x:parse source="${xml}" var="bookInfo"/>

<x:out select="$bookInfo/title"/>

<x:out select="$bookInfo/author"/>

XML类流程控制操作与核心类的流程控制操作一样,包括if, choose, when, otherwise, 和 forEach 这些标记,区别只是它们使用XPath表达式语言。当表达式计算出来后,根据一些规则,结果将转换成一个布尔值。这些规则如下:

A number is true if and only if it is neither positive or negative zero nor NaN.

一个数字当且仅当它不是一个正数,也不是一个负零,更不是一个NaN(非数字)时,表达式的值为真。

A node-set is true if and only if it is non-empty.

一个节点当且仅当它不是空节点时,表达式的值为真。

A string is true if and only if its length is non-zero.

一个字符串当且仅当它的长度不为0是,表达式的值为真。

XML转换操作,是通过XSL样式表来转换XML文档,转换的结果输出到当前页面,另一方面也可以其中的结果保存到变量中。完成一个转换就是导入一个XML文档和XSL样式表,之后做一个转换那么简单:

<c:import url="/books" var="xml"/>

<c:import url="/WEB-INF/xslt/bookDisplay.xsl" var="xslt"/>

<x:transform source="${xml}" xslt="${xslt}"/>

如果你在转换中使用到参数,你可以用<x:param>指定参数名称及参数值。

小结

现在,你已经学会了使用JSTL中的标记,这样,开发JSP会更容易更快捷。留意JSTL的发展,当JSTL的正式版本发布以后,JSP服务器的提供厂商就会对此优化。你可以在http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html中得到JSTL的最后实现版本。 (出处:http://www.knowsky.com)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有