JSTL标签



JSTL标签

JSTL 全名为JavaServer Pages Standard Tag Library,目前最新的版本为1.1。JSTL是由JCP(Java Community Process)所指定的标准规格,它主要提供给Java Web 开发人员一个标准通用的标签函数库。

Web 程序开发人员能够利用JSTL 和EL来开发Web 程序,取代传统直接在页面上嵌入Java程序(Scripting)的做法,以提高程序可读性、维护性和方便性。

本章中,我们将详细介绍如何使用JSTL 中各种不同的标签,将依序介绍条件、循环、URL、U18N、XML、SQL 等标签的用法,让读者对JSTL 有更深层的了解,并且能够学会如何使用JSTL。

 

1 JSTL1.1简介

JavaServer Pages Standard Tag Library (1.1 ),它的中文名称为JSP 标准标签函数库。JSTL是一个标准的已制定好的标签库,可以应用于各种领域,如:基本输入输出、流程控制、循环、XML文件剖析、数据库查询及国际化和文字格式标准化的应用等。从表7-1 可以知道,JSTL所提供的标

签函数库主要分为五大类:

(1)核心标签库 (Core tag library)

(2)I18N 格式标签库 (I18N-capable formatting tag library)

(3)SQL 标签库 (SQL tag library)

(4)XML 标签库 (XML tag library)

(5)函数标签库 (Functions tag library)

 

另外,JSTL 也支持EL(expression_r Language)语法,例如:在一个标准的JSP 页面中可能会使用到如下的写法:

<%= userList.getUser().getPhoneNumber() %>

使用JSTL 搭配传统写法会变成这样:

<c_rt:out value=”<%= userList.getUser( ).getPhoneNumber( ) %>” />

使用JSTL 搭配EL,则可以改写成如下的形式:

<c:out value=”${userList.user.phoneNumber}” />

有关EL的知识请参考相关的资料.

 

7-1-1 安装使用JSTL 1.1

1.1 必须在支持Servlet 2.4 且JSP 2.0 以上版本的Container 才可使用。JSTL 主要由Apache组织的Jakarta Project 所实现,因此读者可以下载实现好的JSTL1.1,

将lib 中的jstl.jar、standard.jar 复制到工程的WEB-INF\lib 中,然后就可以在JSP 网

页中使用JSTL了。除了复制 .jar 文件外,最好也把tld 文件的目录也复制到WEB-INF 中,以便日后使用。

 

注意

lib 目录下,除了jstl.jar 和standard.jar之外,还有old-dependencies目录,这目录里面的东西是让之前JSTL 1.0 的程序也能够在JSTL 1.1 环境下使用。tld 目录下有许多TLD 文件,其中大部分都是JSTL 1.0 的TLD 文件,例如:c-1_0.tld 和c-1_0-rt.tld。

下面写一个测试用的范例程序helloJSTL.jsp,程序主要是显示浏览器的版本和欢迎的字符串。

■ helloJSTL.jsp

<%@ page contentType=”text/html;charset=GB2312″ %>

<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>

<html>

<head>

<title>测试你的第一个使用到JSTL 的网页</title>

</head>

<body>

<c:out value=”欢迎测试你的第一个使用到JSTL 的网页”/>

</br>你使用的浏览器是:</br>

<c:out value=”${header['User-Agent']}”/>

<c:set var=”a” value=”David O’Davies” />

<c:out value=”David O’Davies” escapeXml=”true”/>

</body>

</html>

在helloJSTL.jsp 的范例里,我们用到核心标签库(Core)中的标准输出功能和EL 的header隐含对象。若要在JSP 网页中使用JSTL 时,一定要先做下面这行声明:

< %@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>

这段声明表示我将使用JSTL 的核心标签库。一般而言,核心标签库的前置名称(prefix)都为c,当然你也可以自行设定。不过uri 此时就必须为 http://java.sun.com/jsp/jstl/core。

接下来使用核心标签库中的out 标签,显示value的值。${header['User-Agent']}表示取得表头里的User-Agent 的值,即有关用户浏览器的种类。

<c:out value=”欢迎测试你的第一个使用到JSTL 的网页” />

<c:out value=”${header['User-Agent']}” />

假若读者想要自定义taglib的uri 时,那就必须在web.xml中加入设定值。例如:假若uri想要改为http://www.javaworld.com.tw/jstl/core 时,web.xml 就必须加入如下设定:

<web-app>

<jsp-config>

<taglib>

<taglib-uri>http://www.javaworld.com.tw/jstl/core</taglib-uri>

<taglib-location>/WEB-INF/tld/c.tld</taglib-location>

核心标签库 (Core tag library)

首先介绍的核心标签库(Core)主要有:基本输入输出、流程控制、迭代操作和URL 操作。详细的分类如表7-2 所示,接下来我们将一一介绍每个标签的功能。

表达式操作

表达式操作分类中包含四个标签:<c:out>、<c:set>、<c:remove>和<c:catch>。接下来将依序介绍这四个标签的用法。

● <c:out>

<c:out>主要用来显示数据的内容,就像是 <%= scripting-language %> 一样,例如:

<c:out value=”${username}” />

语法

语法1:没有本体(body)内容

<c:out value=”value” [escapeXml="{true|false}"] [default="defaultValue"] />

语法2:有本体内容

<c:out value=”value” [escapeXml="{true|false}"]>

default value

</c:out>

属性

value 需要显示出来的值

default 如果value的值为null,则显示default属性

escapexml 是否转换特殊字符,如<转换成&lt;

Null 和 错误处理

• 假若value为null,会显示default 的值;假若没有设定default的值,则会显示一个空的字符串。

说明

一般来说,<c:out>默认会将 <、>、’、” 和 & 转换为 &lt;、&gt;、&#039;、&#034; 和 &amp;。假若不想转换时,只需要设定<c:out>的escapeXml 属性为fasle 就可以了

范例

<c:out value=”Hello JSP 2.0 !! ” />

<c:out value=”${ 3 + 5 }” />

<c:out value=”${ param.data }” default=”No Data” />

<c:out value=”<p>有特殊字符</p>” />

<c:out value=”<p>有特殊字符</p>” escapeXml=”false” />

<c:set>

<c:set>主要用来将变量储存至JSP 范围中或是JavaBean 的属性中。

语法

语法1:将 value 的值储存至范围为scope 的 varName 变量之中

<c:set value=”value” var=”varName” [scope="{ page|request|session|application }"]/>

语法2:将本体内容的数据储存至范围为scope 的 varName 变量之中

<c:set var=”varName” [scope="{ page|request|session|application }"]>

… 本体内容

</c:set>

语法3:

将 value 的值储存至 target 对象的属性中

< c:set value=”value” target=”target” property=”propertyName” />

语法4:

将本体内容的数据储存至 target 对象的属性中

<c:set target=”target” property=”propertyName”>

… 本体内容

</c:set>

属性

value 要被存储的值

var 欲存入变量的名称

scope var变量的jsp范围,默认值page

target 为一个javaBean或java.util.Map的对象

property 指定target对象的属性

Null 和 错误处理

语法3 和语法4 会产生异常错误,有以下两种情况:

☆ target 为null

☆ target 不是java.util.Map 或JavaBean 对象

假若value 为null 时:将由储存变量改为移除变量

☆ 语法1:由var 和scope 所定义的变量,将被移除

□ 若scope 已指定时,则PageContext.removeAttribute(varName, scope)

□ 若scope 未指定时,则PageContext.removeAttribute(varName)

☆ 语法3:

□ 假若target 为Map 时,则Map.remove(property)

□ 假若target 为JavaBean 时,property 指定的属性为null

说明

使用<c:set>时,var 主要用来存放表达式的结果;scope 则是用来设定储存的范围,例如:假若scope=”session”,则将会把数据储存在session中。如果<c:set>中没有指定scope时,则它会默认存在Page 范围里。

注意

var 和scope 这两个属性不能使用表达式来表示,例如:我们不能写成

scope=”${ourScope}”或者是var=”${username}”。

我们考虑下列的写法:

<c:set var=”number” scope=”session” value=”${1 + 1}”/>

把1+1的结果2储存到number变量中。如果<c:set>没有value属性,此时value之值在<c:set>

和</c:set>之间,本体内容看下面的范例:

<c:set var=”number” scope=”session”>

<c:out value=”${1+1}” />

</c:set>

上面的 <c:out value=”${1+1}” /> 部分可以改写成2 或是 <%=1+1%> ,结果都会一样,也就是说,<c:set>是把本体(body)运算后的结果来当做value的值。另外,<c:set>会把body 中最开头和结尾的空白部分去掉。如:

<c:set var=”number” scope=”session”>


_____________1 + 1

</c:set>

则number 中储存的值为1 + 1 而不是 1 + 1。

范例

1,<c:set var=”number” scope=”request” value=”${1 + 1}” />

2,<c:set var=”number” scope=”session” />

${3 + 5}

</c:set>

3,<c:set var=”number” scope=”request” value=”${ param.number }” />

4,<c:set target=”User” property=”name” value=”${ param.Username}” />

1.将2 存入Request 范围的number 变量中;

2.将8 存入Session 范围的number 变量中;

3. 假若 ${param.number}为null 时,则移除Request 范围的number变量;若${param.number}不为null 时,则将 ${param.number}的值存入Request 范围的number 变量中;

4.假若 ${param.Username}为null 时,则设定User(JavaBean)的name 属性为null;若不为null 时,则将 ${param.Username}的值存入User(JavaBean)的name 属性(setter 机制)。

注意

上述范例的3.中,假若 ${param.number}为null时,则表示移除Request范围的number变量。

 

 

● <c:remove>

<c:remove>主要用来移除变量。

语法

<c:remove var=”varName” [scope="{ page|request|session|application }"] />

属性

var 欲移除变量名称

scope var变量的jsp范围,默认值page

<c:remove>必须要有var 属性,即要被移除的属性名称,scope 则可有可无,例如:

<c:remove var=”number” scope=”session” />

将number 变量从Session 范围中移除。若我们不设定scope,则<c:remove>将会从Page、

Request、Session 及Application 中顺序寻找是否存在名称为number 的数据,若能找到时,

则将它移除掉,反之则不会做任何的事情。

范例

我们在这里写一个使用到<c:set>和<c:remove>的范例,能让读者可以更快地了解如何使用

它们,此范例的名称为Core_set_remove.jsp。

<c:catch>

<c:catch>主要用来处理产生错误的异常状况,并且将错误信息储存起来。

 

语法

<c:catch [var="varName"] >

… 欲抓取错误的部分

</c:catch>

属性

var 用来存储错误信息的变量

说明

<c:catch>主要将可能发生错误的部分放在<c:catch>和</c:catch>之间。如果真的发生错误,可以将错误信息储存至varName 变量中,例如:

<c:catch var=”message”>

: //可能发生错误的部分

</c:catch>

另外,当错误发生在<c:catch>和</c:catch>之间时,则只有<c:catch>和</c:catch>之间的程序会被中止忽略,但整个网页不会被中止。

范例

我们写一个简单的范例,文件名为Core_catch.jsp,来让大家看一下<c:catch>的使用方式。

流程控制

流程控制分类中包含四个标签:<c:if>、<c:choose>、<c:when>和<c:otherwise>,我们依此顺序依次说明这四个标签的使用。

● <c:if>

<c:if>的用途就和我们一般在程序中用的if 一样。

 

语法

语法1:没有本体内容(body)

<c:if test=”testCondition” var=”varName”

[scope="{page|request|session|application}"]/>

语法2:有本体内容

<c:if test=”testCondition” [var="varName"]

[scope="{page|request|session|application}"]>

具体内容

</c:if>

属性

test 如果表达式结果为true,则执行本体内容,false则相反。类型Bolean

var 用来存储test运算后的结果,即true或false,类型String

scope var变量的jsp范围,默认值page

说明

<c:if> 标签必须要有test 属性,当test 中的表达式结果为true 时,则会执行本体内容;如果为false,则不会执行。例如:${param.username = = ‘admin’},如果param.username 等于admin时,结果为true;若它的内容不等于admin 时,则为false。

接下来看下列的范例:

<c:if test=”${param.username = = ‘admin’ }”>

ADMIN 您好!! //body 部分

</c:if>

如果名称等于admin,则会显示”ADMIN您好!! “的动作,如果相反,则不会执行<c:if>的body部分,所以不会显示”ADMIN 您好!! //body 部分”。另外<c:if>的本体内容除了能放纯文字,还可以放任何JSP 程序代码(Scriptlet)、JSP 标签或者HTML 码。除了test 属性之外,<c:if>还有另外两个属性var和scope。当我们执行<c:if>的时候,可以将这次判断后的结果存放到属性var 里;scope 则是设定var 的属性范围。哪些情况才会用到var和scope 这两个属性呢?例如:当表达式过长时,我们会希望拆开处理,或是之后还须使用此结果

时,也可以用它先将结果暂时保留,以便日后使用。

范例

我们写了一个简单的范例,名称为Core_if.jsp。

■ Core_if.jsp

<%@ page contentType=”text/html;charset=GB2312 ” %>

<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>

<html>

<head>

<title>CH7 – Core_if.jsp</title>

</head>

<body>

<h2><c:out value=”<c:if> 的用法” /></h2>

<c:if test=”${param.username == ‘Admin’}” var=”condition” scope=”page”>

您好Admin 先生

</c:if></br>

执行结果为: ${condition}

</body>

</html>

我们在判断用户送来的参数时,如果username 的值等于Admin 时,则会将condition 设为true并存放于pageScope中,否则存放于condition中,最后再显示结果。因为JSTL会自动找寻condition所存在的属性范围,因此只须使用 ${condition},而不用 ${pageScope.condition}。

 

<c:choose>

<c:choose>本身只当做 <c:when> 和 <c:otherwise> 的父标签。

语法

<c:choose>

本体内容( <when> 和 <otherwise> )

</c:choose>

 

限制

<c:choose>的本体内容只能有:

•空白

•1 或多个 <c:when>

•0 或多个 <c:otherwise>

说明

若使用<c:when>和<c:otherwise>来做流程控制时,两者都必须为<c:choose>的子标签,即:

<c:choose>

<c:when>

</c:when>

<c:otherwise>

</c:otherwise>

</c:choose>

<c:when>

<c:when> 的用途就和我们一般在程序中用的when 一样。

语法

<c:when test=”testCondition” >

本体内容

</c:when>

属性

test 如果表达式的结果为true,则执行本体内容,否则相反

限制

☆ <c:when>必须在<c:choose>和</c:choose>之间

☆ 在同一个<c:choose>中时,<c:when>必须在<c:otherwise>之前

说明

<c:when>必须有test 属性,当test 中的表达式结果为true 时,则会执行本体内容;如果为false 时,则不会执行。