jstl简介及自己项目中所用到的jstl

来源:互联网 发布:米表cms 编辑:程序博客网 时间:2024/05/16 15:47

本文分三部分,第一部分介绍jstl,第二部分介绍如何在项目中导入jstl,第三部分介绐在项目中常用到的jstl及其用法.

1:JSTL 1.0 发布于 2002 年 6 月,由四个定制标记库(core、format、xml 和 sql)和一对通用标记库验证器(ScriptFreeTLV 和 PermittedTaglibsTLV)组成。core 标记库提供了定制操作,通过限制了作用域的变量管理数据,以及执行页面内容的迭代和条件操作。它还提供了用来生成和操作 URL 的标记。顾名思义,format 标记库定义了用来格式化数据(尤其是数字和日期)的操作。它还支持使用本地化资源束进行 JSP 页面的国际化。xml 库包含一些标记,这些标记用来操作通过 XML 表示的数据,而 sql 库定义了用来查询关系数据库的操作。


表达式语言
  在 JSP 1.2 中,可以使用静态字符串或表达式(如果允许的话)指定 JSP 操作的属性。例如,在清单 2 中,对 <jsp:setProperty> 操作的 name 和 property 属性指定了静态值,而用表达式指定了其 value 属性。这个操作的效果是将请求参数的当前值赋予命名的 bean 特性。以这种形式使用的表达式被称为请求时属性值(request-time attribute value),这是构建到 JSP 规范中的用于动态指定属性值的唯一机制。
  清单 2. 合并请求时属性值的 JSP 操作
<jsp:setProperty name="user" property="timezonePref" value='<%= request.getParameter("timezone") %>'/>
  因为请求时属性值是用表达式指定的,所以它们往往有和其它脚本元素一样的软件维护问题。因此,JSTL 定制标记支持另一种用于指定动态属性值的机制。可以用简化的表达式语言(EL)而不使用完整的 JSP 表达式来指定 JSTL 操作的属性值。EL 提供了一些标识符、存取器和运算符,用来检索和操作驻留在 JSP 容器中的数据。EL 在某种程度上以 EcmaScript(请参阅参考资料)和 XML 路径语言(XML Path Language,XPath)为基础,因此页面设计人员和程序员都应该熟悉它的语法。EL 擅长寻找对象及其特性,然后对它们执行简单操作;它不是编程语言,甚至不是脚本编制语言。但是,与 JSTL 标记一起使用时,它就能使用简单而又方便的符号来表示复杂的行为。EL 表达式的格式是这样的:用美元符号({ })中,如清单 3 所示。
  清单 3. 说明 EL 表达式定界符的 JSTL 操作
  <c:out value="${ user.firstName}"/>
  此外,您可以将多个表达式与静态文本组合在一起以通过字符串并置来构造动态属性值,如清单 4 所示。单独的表达式由标识符、存取器、文字和运算符组成。标识符用来引用存储在数据中心中的数据对象。EL 有 11 个保留标识符,对应于 11 个 EL 隐式对象。假定所有其它标识符都引用限制了作用域的变量。存取器用来检索对象的特性或集合的元素。文字表示固定的值 — 数字、字符、字符串、布尔型或空值。运算符允许对数据和文字进行组合以及比较。
  清单 4. 组合静态文本和多个 EL 表达式以指定动态属性值
  <c:out value="Hello ${ user.firstName} ${ user.lastName}"/>

限制了作用域的变量
  JSP API 通过 <jsp:useBean> 操作允许从 JSP 容器内的四个不同作用域中存储和检索数据。JSTL 通过提供用于指定和除去这些作用域中的对象的附加操作来扩展这一能力。此外,EL 提供将这些对象作为限制了作用域的变量进行检索的内置支持。特别地,任何出现在 EL 表达式中但不对应于任何 EL 隐式对象的标识符,都被自动假定为引用存储在四个 JSP 作用域的其中某个中的对象,这四个作用域是:
  ·页面作用域
  ·请求作用域
  ·会话作用域
  ·应用程序作用域


隐式对象
  表 1 中列出了 11 个 EL 隐式对象的标识符。不要将这些对象与 JSP 隐式对象(一共只有九个)混淆,其中只有一个对象是它们所共有的。
  表 1. EL 隐式对象
  类别    标识符             描述
  JSP    pageContext   PageContext 实例对应于当前页面的处理
  作用域  pageScope     与页面作用域属性的名称和值相关联的 Map 类
       requestScope   与请求作用域属性的名称和值相关联的 Map 类
       sessionScope   与会话作用域属性的名称和值相关联的 Map 类
       applicationScope 与应用程序作用域属性的名称和值相关联的 Map 类
  请求参数 param      按名称存储请求参数的主要值的 Map 类
       paramValues  将请求参数的所有值作为 String 数组存储的 Map 类
  请求头  header     按名称存储请求头主要值的 Map 类
       headerValues 将请求头的所有值作为 String 数组存储的 Map 类
  Cookie  cookie     按名称存储请求附带的 cookie 的 Map 类
  初始化参数 initParam   按名称存储 Web 应用程序上下文初始化参数的 Map 类
    尽管 JSP 和 EL 隐式对象中只有一个公共对象(pageContext),但通过 EL 也可以访问其它 JSP 隐式对象。原因是 pageContext 拥有访问所有其它八个 JSP 隐式对象的特性。实际上,这是将它包括在 EL 隐式对象中的主要理由。
  其余所有 EL 隐式对象都是映射,可以用来查找对应于名称的对象。前四个映射表示先前讨论的各种属性作用域。可以用它们来查找特定作用域中的标识符,而不用依赖于 EL 在缺省情况下使用的顺序查找过程。
  接下来的四个映射用来获取请求参数和请求头的值。因为 HTTP 协议允许请求参数和请求头具有多个值,所以它们各有一对映射。每对中的第一个映射返回请求参数或头的主要值,通常是恰巧在实际请求中首先指定的那个值。每对中第二个映射允许检索参数或头的所有值。这些映射中的键是参数或头的名称,但这些值是 String 对象的数组,其中的每个元素都是单一参数值或头值。
  cookie 隐式对象提供了对由请求设置的 cookie 名称的访问。这个对象将所有与请求相关联的 cookie 名称映射到表示那些 cookie 特性的 Cookie 对象。
  最后一个 EL 隐式对象 initParam 是一个映射,它储存与 Web 应用程序相关联的所有上下文的初始化参数的名称和值。初始化参数是通过 web.xml 部署描述符文件指定的,该文件位于应用程序的 WEB-INF 目录中。


存取器
  因为 EL 标识符是作为隐式对象或限制了作用域的变量(通过属性来实现)解析的,因此有必要将它们转换成 Java 对象。EL 可以自动包装和解包其相应的 Java 类中的基本类型(例如,可以在后台将 int 强制转换成 Integer 类,反之亦可),但大多数的标识符将成为指向完整的 Java 对象的指针。
  结果是,对这些对象的特性或(在对象是数组和集合的情况下)对其元素的访问通常是令人满意的。就为了实现这种用途,EL 提供了两种不同的存取器(点运算符(.)和方括号运算符([])),也支持通过 EL 操作特性和元素。
  点运算符通常用于访问对象的特性。例如,在表达式 ${ user.firstName} 中,使用点运算符来访问 user 标识符所引用对象的名为 firstName 的特性。EL 使用 Java bean 约定访问对象特性,因此必须定义这个特性的 getter 方法(通常是名为 getFirstName() 的方法),以便表达式正确求值。当被访问的特性本身是对象时,可以递归地应用点运算符。例如,如果我们虚构的 user 对象有一个实现为 Java 对象的 address 特性,那么也可以用点运算符来访问这个对象的特性。例如,表达式 ${ user.address.city} 将会返回这个地址对象嵌套的 city 特性。
  方括号运算符用来检索数组和集合的元素。在数组和有序集合(也即,实现了 java.util.List 接口的集合)的情况下,把要检索的元素的下标放在方括号中。例如,表达式 ${ urls[3]} 返回 urls 标识符所引用的数组或集合的第四个元素(和 Java 语言以及 JavaScript 中一样,EL 中的下标是从零开始的)。
  对于实现 java.util.Map 接口的集合,方括号运算符使用关联的键查找存储在映射中的值。在方括号中指定键,并将相应的值作为表达式的值返回。例如,表达式 ${ commands["dir"]} 返回与 commands 标识符所引用的 Map 中的 "dir" 键相关联的值。
  对于上述两种情况,都可允许表达式出现在方括号中。对嵌套表达式求值的结果将被作为下标或键,用来检索集合或数组的适当元素。和点运算符一样,方括号运算符也可以递归应用。这使得 EL 能够从多维数组、嵌套集合或两者的任意组合中检索元素。此外,点运算符和方括号运算符还可以互操作。例如,如果数组的元素本身是对象,则可以使用方括号运算符来检索该数组的元素,并结合点运算符来检索该元素的一个特性(例如 ${ urls[3].protocol})。
  假定 EL 充当指定动态属性值的简化语言,EL 存取器有一个有趣的功能(与 Java 语言的存取器不同),那就是它们在应用于 null 时不抛出异常。如果应用 EL 存取器的对象(例如,${ foo.bar} 和 ${ foo["bar"]} 中的 foo 标识符)是 null,那么应用存取器的结果也是 null。事实证明,在大多数情况下,这是一个相当有用的行为,不久您就会了解这一点。
  最后,点运算符和方括号运算符可能实现某种程度的互换。例如,也可以使用 ${ user["firstName"]} 来检索 user 对象的 firstName 特性,正如可以用 ${ commands.dir} 获取与 commands 映射中的 "dir" 键相关联的值一样。


运算符
  EL 还可以通过使用标识符和存取器,遍历包含应用程序数据(通过限制了作用域的变量公开)或关于环境的信息(通过 EL 隐式对象)的对象层次结构。但是,只是访问这些数据,通常不足以实现许多 JSP 应用程序所需的表示逻辑。
  最终,EL 还包括了几个用来操作和比较 EL 表达式所访问数据的运算符。表 2 中汇总了这些运算符。
  表 2. EL 运算符
  类别     运算符
  算术运算符  +、-、*、/(或 div)和 %(或 mod)
  关系运算符  ==(或 eq)、!=(或 ne)、<</code>(或 lt)、>(或 gt)、<=(或 le)和 >=(或 ge)
  逻辑运算符  &&(或 and)、||(或 or)和 !(或 not)
  验证运算符  empty
  算术运算符支持数值的加法、减法、乘法和除法。还提供了一个求余运算符。注:除法和求余运算符都有替代的、非符号的名称(为的是与 XPath 保持一致)。清单 5 中显示了一个演示算术运算符用法的示例表达式。对几个 EL 表达式应用算术运算符的结果是将该算术运算符应用于这些表达式返回的数值所得的结果。
  清单 5. 利用算术运算符的 EL 表达式
${ item.price * (1 + taxRate[user.address.zipcode])}
  关系运算符允许比较数字或文本数据。比较的结果作为布尔值返回。逻辑运算符允许合并布尔值,返回新的布尔值。因此,可以将 EL 逻辑运算符应用于嵌套的关系或逻辑运算符的结果,如清单 6 所示。
  清单 6. 利用关系和逻辑运算符的 EL 表达式
${ (x >= min) && (x <= max)}
  最后一种 EL 运算符是 empty,它对于验证数据特别有用。empty 运算符采用单个表达式作为其变量(也即,${ empty input}),并返回一个布尔值,该布尔值表示对表达式求值的结果是不是“空”值。求值结果为 null 的表达式被认为是空,即无元素的集合或数组。如果参数是对长度为零的 String 求值所得的结果,则 empty 运算符也将返回 true。
  表 3 显示了 EL 运算符的优先级。正如清单 5 和 6 所示,可以用圆括号对表达式分组,高于普通的优先级规则。
  表 3. EL 运算符优先级(自顶到底,从左到右)
[], . () unary -、not、!、empty *、/、div、%、mod +、binary - () <</code>、>、<=、>=、lt、gt、le、ge ==、!=、eq、ne &&、and ||、or


变量标记
  我们首先要考虑的 JSTL 定制标记是 <c:set> 操作。正如已经说明的,限制了作用域的变量在 JSTL 中起关键作用,<c:set> 操作提供基于标记的机制来创建和设置限制了作用域的变量。清单 9 中显示了该操作的语法,其中 var 属性指定了限制了作用域的变量的名称,scope 属性表明了该变量驻留在哪个作用域中,value 属性指定了分配给该变量的值。如果指定变量已经存在,则简单地将所指明的值赋给它。如果不存在,则创建新的限制了作用域的变量,并用该值初始化这个变量。
  清单 9. <c:set> 操作的语法
<c:set var="name" scope="scope" value="expression"/>
  scope 属性是可选的,其缺省值是 page。
  清单 10 中显示了 <c:set> 的两个示例。在第一个示例中,将会话作用域变量设置成 String 值。在第二个示例中,用表达式来设置数值:将页面作用域内名为 square 的变量赋值为名为 x 的请求参数的值的平方。
  清单 10. <c:set> 操作示例
<c:set var="timezone" scope="session" value="CST"/> <c:set var="square" value="${ param['x'] * param['x']}"/>
  您还可以将限制了作用域的变量的值指定为 <c:set> 操作的主体内容,而不是使用属性。使用这种方法,您可以重新编写清单 10 中的第一个示例,如清单 11 所示。此外,正如我们马上可以看到的,<c:set> 标记的主体内容本身也可以使用定制标记。<c:set> 主体内生成的所有内容都将作为一个 String 值赋给指定变量。
  清单 11. 通过主体内容指定 <c:set> 操作的值
<c:set var="timezone" scope="session">CST</c:set>
JSTL core 库包含第二个用于管理限制了作用域的变量的标记 — <c:remove>。顾名思义,<c:remove> 操作是用来删除限制了作用域的变量的,它获取两个属性。var 属性指定待删除变量的名称,scope 属性是可选的,它表示待删除变量来自哪个作用域,缺省为 page,如清单 12 所示。
  清单 12. <c:remove> 操作示例
<c:remove var="timezone" scope="session"/>

 


输出
  尽管 <c:set> 操作允许将表达式结果赋给限制了作用域的变量,但开发人员通常会希望只显示表达式的值,而不存储它。JSTL <c:out> 定制标记承担这一任务,其语法如清单 13 所示。该标记对由其 value 属性指定的表达式进行求值,然后打印结果。如果指定了可选属性 default,那么,在对 value 属性的表达式求值所得结果为 null 或空 String 的情况下,<c:out> 将打印其值。
  清单 13. <c:out> 操作的语法
<c:out value="expression" default="expression" escapeXml="boolean"/>
  escapeXml 属性也是可选的。它控制当用 <c:out> 标记输出诸如“<”、“>”和“&”之类的字符(在 HTML 和 XML 中具有特殊意义)时是否应该进行转义。如果将 escapeXml 设置为 true,则会自动将这些字符转换成相应的 XML 实体(此处提到的字符分别转换成 &lt;、&gt; 和 &amp;)。
  例如,假定有一个名为 user 的会话作用域变量,它是一个类的实例,该类为用户定义了两个特性:username 和 company。每当用户访问站点时,这个对象被自动分配给会话,但直到用户实际登录后,才会设置这两个特性。假定是这种方案,请考虑清单 14 中的 JSP 片段。在用户登录之后,这个片段将显示单词“Hello”,其后是他/她的用户名和一个惊叹号。但是,在用户登录之前,由这个片段生成的内容则是短语“Hello Guest!”。在这种情况下,因为 username 特性还有待初始化,所以 <c:out> 标记将转而打印出 default 属性的值(即字符串“Guest”)。
  清单 14. 带缺省内容的 <c:out> 操作示例 Hello
<c:out value="${ user.username}" default=="Guest"/>!
  接下来,考虑清单 15,它使用了 <c:out> 标记的 escapeXml 属性。如果在这种情况下已经将 company 特性设置成 Java String 值 "Flynn & Sons",那么,实际上该操作生成的内容将是 Flynn & Sons。如果这个操作是生成 HTML 或 XML 内容的 JSP 页面的一部分,那么,这个字符串中间的“&”符号最终可能被解释为 HTML 或 XML 控制字符,从而妨碍了对该内容的显示或解析。但是,如果将 escapeXml 属性值设置成 true,则所生成的内容将是 Flynn &amp; Sons。浏览器或解析器不会因在解释时遇到这种内容而出问题。假定 HTML 和 XML 是 JSP 应用程序中最常见的内容类型,所以 escapeXml 属性的缺省值是 true 就不足为奇了。
  清单 15. 禁用转义的 <c:out> 操作示例
<c:out value="${ user.company}" escapeXml=="false"/>

<c:choose>
       <c:when test="${ user.role == 'member'}"> <p>Welcome, member!</p> </c:when>
       <c:otherwise> <p>Welcome, guest!</p> </c:otherwise>
</c:choose>

 

2:如何在项目上导入jstl

 1:首先把两个包加到工程中jstl.jar和standard.jar
2:把标签文件加到web-info下:13个
3:在web.xml文件中加入:这里一定要注意路径
<jsp-config>
    <taglib>
        <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
        <taglib-location>/WEB-INF/taglib/c.tld</taglib-location>
    </taglib>
    <taglib>
        <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
        <taglib-location>/WEB-INF/taglib/fmt.tld</taglib-location>
    </taglib>
  </jsp-config>
4:在用到jstl和jsp中加上导入标签的指令
<%@ taglib uri="/WEB-INF/taglib/c.tld" prefix="c" %>
<%@ taglib uri="/WEB-INF/taglib/fmt.tld" prefix="fmt" %>
好了.这样就OK了

 

 

3:上面的jstl简介可能都见过,但真正用到是我在项目中用到的,

1:日期格式化:
<fmt:formatDate value="${item['CZRQ']}" pattern='yyyy年MM月dd日 HH:mm:ss'/>

2:金额格式化:
<fmt:formatNumber value="${item['XJE']-item['YJE']}" pattern="0.00"/>
fmt:formatNumber动作有一个value属性和一个pattern属性。value属性是一个与我们看到的其它value属性类似的EL表达式或者变量。pattern属性与在NumberFormat类中定义的模式一样。下列动作发送一个格式化的String到JSP页的输出上: <fmt:formatNumber value="1000.001" pattern="#,#00.0#"/>
在这个fmt:formatNumber动作里,我们使用了type属性来指定:格式化我们需要格式化的值为一个货币值。我们保存格式化的结果在一个变量名为dollars中。在一个美国的locale类中,下面的程序生成一个字符串$3456.79(注意,它将使用的货币值四舍五入了):

<fmt:formatNumber value="3456.789" type="currency" var="dollars"/>
<fmt:formatNumber value="${item['HTL']}" pattern="#.##%" />

用于上面的type属性的可能值包括currency、 number、 和percent。

3:导入页面并传参数
<c:import url="/common/splitpage2.jsp">
     <c:param name="pageurl">/fsrgl/list_hmd.jsp</c:param>
</c:import>

4:跳转页面(MSG为作用中的KEY)
<c:if test="${(MSG_OK ne null) or (MSG_ERROR ne null)}">
    <jsp:forward page="/common/message.jsp" />
</c:if>

5:最常用的<c:forEach>

常用标签示例
<c:forEach var="item" items="${list}" varStatus="status">
                                  <c:choose>
                                   <c:when test="${status.count mod 2==0 }"><tr bgcolor="E8F2F4" class="hui666"></c:when>
                                   <c:otherwise><tr class="hui666"></c:otherwise>
                                  </c:choose>
           <td height="22"><c:out value="${item['MC']}" /></td>
           <td height="22"><c:out value="${item['QYDH']}" /></td>
           <td><a href="#" onclick="javascript:contactMe('<c:out value='${item["QYDH"]}'/>','<c:out value='${item["FL"]}'/>','<c:out value='${item["MC"]}'/>');"><img border="0" src="<c:out value='${WebRoot}'/>/images/dial-btn.gif" width="106" height="19"/></a></td>
           <td class="hui666">
            <a class="hui666" href="#" onclick="edit('<c:out value='${item["QYDH"]}'/>','<c:out value="${item['MC']}" />','<c:out value="${item['BH']}" />','<c:out value="${item['FL']}" />')">编辑</a>/<a class="hui666" href="#" onclick="delPhone('<c:out value="${item['BH']}" />')" >删除</a>
           </td>
          </tr>
         </c:forEach>