在本篇文章中,我们将会深入了解在不同的Tag Library描述符(Tag Library Descriptors:TLDs)中使用各种不同的tag的情况.我们将会依次研究 条件、循环、URL、U18N、XML等tag的用法。以此来提高你对JSTL的认识和应用能力,在阅读本文前,你应该对 JSP Tag Lib有所了解,并清晰有关JSTL(JSP Standard Tag Libraries)的基本知识 ,可参看 《JSP Standard Tag Library (JSTL)介绍》一文
JSP Standard Tag Libraries 实践理解
在本篇文章中,我们将会深入了解在不同的Tag Library描述符(Tag Library Descriptors:TLDs)中使用各种不同的tag的情况.我们将会依次研究 条件、循环、URL、U18N、XML等tag的用法。以此来提高你对JSTL的认识和应用能力,在阅读本文前,你应该对 JSP Tag Lib有所了解,并清晰有关JSTL(JSP Standard Tag Libraries)的基本知识 ,可参看 《JSP Standard Tag Library (JSTL)介绍》一文
JSTL是一组标准的已制定好的操作,他们应用于各种功能领域。在JSR-52(Java Specification Request)中的定义中,JSTL包含了 expression language(EL)、流程控制 和Tag Library较验器。有关最终版本,你能产看 http://www.jcp.org/jsr/detail/52.jsp 上的最终草案
JSTL需要运行在JSP 1.2的容器下,他是用来简化JSP的研发,提供更加的方式处理和访问应用数据.
JSTL包含了多中Tag Library的描述定义(TLDs),这些描述位于一个JAR文件中.这些TLDs涵盖了大多数的功能操作,下面我们会逐一列举,不过在此之前,我们会重点讨论expression language,他可能算是JSTL中最重要的特征了.
expression language (EL)其实是由制定JSR-152(Java Server Pages 1.3 Specification)的专家组制定的,事实上非常可能EL就将会是JSP 1.3的重要组成部分.EL(目前还是叫SPEL:Simplest Possible Expression Language )提供了一些简单的语法来直接访问应用数据,支持操作符、Bean、集合,更有类型自动转换、属性的默认值定义等等。
EL的用法:
EL总处在在${...}中(就象JSP 在<%...%>中那样)。在属性中只允许出现一个表达式,例如:
<c:if test="${product.price >= customer.limit}">
...
</c:if>
在上面的例子中,我们使用EL进行比较操作,他还能和静态文本混合使用,能看看下面这个例子:
<c:forEach var="current">
<c:out value="Product-${current}"/>
</c:forEach>
在这个例子中我们循环遍历一个集合,把current值按一定的文本形式显示出来,结果如下:
Product-1
Product-2
Product-3...
从这个例子你也能看出,使用EL比以前的编码简单了非常多。在出现JSTL之前,你需要通过先定义对象、了解对象类型、使用相应的脚本来完成一个非常简单的操作。
目前有了JSTL,能使用更加简单的语法进行操作,你看这个例子:
<jsp:useBean id="customer" type="sample.Customer" scope="request"/> ...
Customer Name: <%=customer.getName()%>
...
<% if (customer.getState().equals("CO")){ %>
...
<%}%>
目前能使用EL写成:
Customer Name: ${ customer. name}
<c:if test="${customer. state == param. state}">
...
</c:if>
EL支持直接访问所有的JSP数据域(JSP scopes)的变量,比如我们使用${foo}来代替pageContext.findAttributes("foo")的写法,EL是使用"."号来使用bean的属性,比如:
${user.address.city}
${products.[product.id]}
${products.["Part-010"]}
EL包含了多种操作符:==, !=, <,>, <=, and >=, &&, ||, ! .为了避免和XML冲突,更有一些如lt, gt, le, ge, eq, 和 ne的操作符,及+、-、/、*、%等算数运算符,更有Boolean运算符and, or, not, 和 empty.EL的另一个特征就是自动类型转换,比如:int value = "${request.myValue}",不会报错,EL会把string 转化成int
另外EL还为变量提供默认的值.这样会避免出现"对空数据操作"的异常.如下的例子显示了怎么给变量设置默认值 <c:set var="city" value="${user.address.city}" default="N/A" />
目前我们来了解一下EL所支持的操作:
核心操作
EL处在核心tag库中,使用<c:out>tag来表示把EL表达式输出到当前的JspWriter中,他非常像JSP的<%= scripting exp %> 表达式。比如下面这个例子:
<c:out value="${customer.name}" default="N/A" />
EL还能设置和删除某个值域中的变量,默认的值域是Page值域(JSP所支持的值域包括application sessionpage 等值域),例如我们使用<c:set var="customer" value=${customer}" />来设置一个Page值域的变量,然后能使用<c:remove var="customer" />来删除他
我们还能使用JSTL的tag来catch ava.lang.Throwable,比如:<c:catch var="myError" />,该tag用于统一page中的异常处理。他并意味着完全代替了JSP的出错机制,只是使用这样的tag能更富条例的控制异常;不必把作有的错误都导入出错页面,有些错误不必这样处理,使用<c:catch> tag能设计更友好的用户交互
条件操作
相比JSP代码,EL在条件控制上也非常强大,使用<c:if>tag就能构造一个条件表达式,看这个例子:
<c:if test="${user.visitCount == 1}">
Welcome back!
</c:if>
你能看到这是个 if 语句,当然更有其他的条件控制符,<c:choose>, <c:when>,和 <c:otherwise>tag也能表达出 "if/then/else"的功能
让我们来看这样一个例子,如果我们需要处理一些结果,能使用这些tag来为相应的情况显示相应消息:
<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中最有用的特性就是循环操作了,JSTL中支持循环操作的tag是 <c:forEach>, <c:forToken>, 和 <x:forEach>,更有一些模仿了核心tag用于XML操作的tags,我们稍后介绍,先来看看这些核心tag中的循环操作.
这些操作支持所有的标准的J2SE的集合类型,包括 List, LinkedList, ArrayList, Vector, Stack, 和 Set。还包括java.util.Map类的对象比如HashMap, Hashtable, Properties, Provider, 和 Attributes。当然还能循环遍历对象或基本类型的数组。当使用基本类型时注意,在数组中的项目是他们相应的包装类,比如一个int数组中的元素是Integer,每次循环输入两个对象:当前的元素和循环状态,让我们来看看下面这个例子:
<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>
从这个例子我们能看出,EL把products变量作为集合,每一次输出的当前项设为product,当前状态设为status。
URL操作
除了循环操作,核心tag中还包括URL相关的操作。他提供了诸如hyperlinks, resource import, 和 redirect 的功能。使用<c:url>tag能方便的处理URL的rewriting 和 encoding,让我们来看看下面这个例子:
<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中resource imports也是一项强大的功能,能方便的指定绝对或相对的路径的外部资源及FTP资源,我们来看一些例子:
Absolute URL: <c:import url="http://sample.com/Welcome.html"/>
Relative URL (to the current context): <c:import url="/copyright.html"/>
Relative URL with a foreign context: <c:import url="/myLogo.html" context="/common"/>
FTP resource: <c:import url="ftp://ftp.sample.com/myFile"/>
从这些例子我们能看出,<c:import>提供了比<jsp:include>更多的功能,他另外一个好处是能避免资源内容被多次读入,比如,当你在格式转换(transformation,比如XML通过XSL转换)中使用<jsp:include>来import资源,在include时读入一次,然后所有内容被写入JspWriter,在格式转换中还要被读入一次,使用<c:import>,内容只被读入一次,不写入JspWriter,然后再交由格式转换tag处理
我们还能把导入的资源作为一个String或Reader对象来使用,使用varReader或var属性来定义对象名。这个对象是可重用的,并自己有自己的缓冲(cache).使用Reader的能直接读取数据而没所有暂存(buffering),使用声明过的Reader,必须把他嵌入在 <c:import> 和 </c:import>中使用,比如像下面这个例子
<c:import url=http://sample.com/customers varReader="customers">
<mytag:process in="${customers}"/>
</c:import>
国际化问题
JSTL中的另一个重要功能是他的国际化格式支持(I18N)。该功能能对一个特定的语言请求作出相应的响应。他使用了J2SE 的ResourceBundle来保持各种翻译过的语言编码,JSTL会根据不同的地区选择适合的ResourceBundle。<fmt:setLocale>用来设置地区,比如<fmt:setLocale value="es_Es"/>,这等和设定了语言和国家代码。当然还能指定ResourceBundle,比如:<fmt:bundle basename="ApplicationResource_fr"/>
一旦设定了locale(地区)或ResourceBundle,就能使用<fmt:message>来把原文进行相应的转化,同时还能进行参数替换,比如:
<fmt:message key="welcome">
<fmt:param value="${visitCount}" />
<fmt:message/>
You can also use < fmt:requestEncoding/> to set the request´s character encoding.
你还能使用< fmt:requestEncoding/>来设定请求的字符编码
能正确显示字符,还只是国际化问题的一半.还必须解决数字和时间的格式解析。不同的地区有不同的显示方法。使用<fmt:formatNumber> 或<fmt:parseNumber> 能按当地的格式显示数字、货币金额、百分比。同时还能制定模式(pattern)参数,比如<fmt:formatNumber value="12.3" pattern=".00"/>会输出"12.30."
时间和日期使用<fmt:formatDate>, <fmt:timeZone>, <fmt:setTimeZone>, 和 <fmt:parseDate>来处理
SQL操作
SQL操作支持直接访问数据源。在MVC模式中这种做法是会受到警告的,我个人也反对在产品中使用这样的tag,不过对一些快速、小型、简单的研发,他还是会有一些作用,不过不要把他应用到大型应用系统中去。我们来看看SQL操作提供了一些什么功能
能使用这些tag来设定数据源、查询数据库、非常容易的访问查询结果并能事务性的更新数据。看下面这个例子怎么设定数据源:
<sql:setDataSource var="datasource" driver="org.gjt.mm.mysql.driver" url="jdbc:mysql://localhost/db" />
<sql:setDataSource>仅仅是封装了JDBC DriverManager的功能。datasource的属性能是String或JNDI的相对路径或JDBC 参数串.然后在查询中我们能这样使用datasource:<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> tag 能设定在 SQL语句中java.util.Date类型的 "?"( parameter markers).在这个例子中没有展示事务级的设定,事务级在java.sql.Connection中设定,如果没有设定事务级,然后在tag中使用他,就会抛出JspTagException.
XML操作
最后我们来看看XML操作,XML操作集是在核心、流程控制、转向操作外的一个操作集,他是建立在Xpath上的。使用Xpath表达式。
XML 的核心操作非常像JSTL中核心操作,包括<x:out>, <x:set>, 和<x:parse>,不同是这些操作tag支持的是XPath表达式的。<x:parse>用来把XML文件解析成数据,数据由XPath引擎处理,如果我们有一个描述一本书的XML文件,我们能解析他,并使用XPath表达式显示他
<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 tag,不同的是他们使用XPath表达式.结果对象会按XPath的语义定义转化成相应的boolean值,这些语义规定是:
当且仅当一个数是非零正数或非NaN(无穷大)时为true
当且仅当一个节点不为空时,值为true
当且仅当一个字串的长度不为零时该子串为true
XML的转换操作是把XML文件用XSL样式文件显示,但不能获得这些结果,把他们存储在某个变量或值域的属性中,这样的操作只是引入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中的一些有用的tag,他能使你的JSP文件变的简单易用。请关注JSTL的发展,当他的最终草案完成后,我们就能看到各个厂商针对JSTL对他们的JSP container的调整,如果你目前就想要实践一下,能下载JSTL目前最新的版本:jakarta ´s JSTL.
About author
Sue Spielman is an associate editor for ONJava.com, covering JSP and Servlets technologies. She is also president - and is one of the many Java expert engineers - for Switchback Software LLC. Switchback Software specializes in consulting on and building Java enterprise business, web, and wireless applications for companies large and small.
英文原文:JSP Standard Tag Libraries, Part 2
转载自 http://mag.javadigest.net
JSP Standard Tag Libraries 实践理解
最新推荐文章于 2020-03-02 15:09:07 发布