JSEL 表达式
JSTL標簽庫的使用是為類彌補html表的不足,規范自定義標簽的使用而誕生的。在告別modle1模式開發應用程序后,人們開始注重軟件的分層設計,不希望在jsp頁面中出現java邏輯代碼,同時也由于自定義標簽的開發難度較大和不利于技術標準化產生了自定義標簽庫。JSTL標簽庫可分為5類:
? ? ? ?核心標簽庫
? ? ? ? I18N格式化標簽庫
? ? ? ? SQL標簽庫
? ? ? ? XML標簽庫
? ? ? ? 函數標簽庫
本章將對這些內容一一講述。
9.1?核心標簽庫
JSTL的核心標簽庫標簽共13個,從功能上可以分為4類:表達式控制標簽、流程控制標簽、循環標簽、URL操作標簽。使用這些標簽能夠完成JSP頁面的基本功能,減少編碼工作。
(1)表達式控制標簽:out標簽、set標簽、remove標簽、catch標簽。
(2)流程控制標簽:if標簽、choose標簽、when標簽、otherwise標簽。
(3)循環標簽:forEach標簽、forTokens標簽。
(4)URL操作標簽:import標簽、url標簽、redirect標簽。
在JSP頁面引入核心標簽庫的代碼為:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
下面將按照功能分類,分別講解每個標簽的功能和使用方式。
9.2.1?表達式控制標簽
表達式控制分類中包括<c:out>、<c:set>、<c:remove>、<c:chtch>4個標簽,現在分別介紹它們的功能和語法。
1.<c:out>標簽
【功能】:用來顯示數據對象(字符串、表達式)的內容或結果。
在使用Java腳本輸出時常使用的方式為:
<% out.println(“字符串”)%>
<%=表達式%>
在web開發中,為了避免暴露邏輯代碼會盡量減少頁面中的Java腳本,使用<c:out>標簽就可以實現以上功能。
<c:out value=”字符串”>
<c:out value=”EL表達式”>
提示:JSTL的使用是和EL表達式分不開的,EL表達式雖然可以直接將結果返回給頁面,但有時得到的結果為空,<c:out>有特定的結果處理功能,EL的單獨使用會降低程序的易讀性,建議把EL的結果輸入放入<c:out>標簽中。
<c:out>標簽的使用有兩種語法格式。
【語法1】:
<c:out value=”要顯示的數據對象” [escapeXml=”true|false”] [default=”默認值”]>
【語法2】:
<c:out value=”要顯示的數據對象” [escapeXml=”true|false”]>默認值
</c:out>
這兩種方式沒有本質的區別,只是格式上的差別。標簽的屬性介紹如下。
q????????value:指定要輸出的變量或表達式。
q????????escapeXml:設定是否轉換特殊字符(如<、>等一些轉義字符),在默認值為true的情況下直接在輸出<的,如果改為false將會進行轉義輸出“<”等。
q????????default:為默認輸出結果。如果使用表達式得到的結果為null(注意與空區別),將會輸出默認結果。
【示例代碼】:代碼9.1演示了<c:out>的使用,以及在不同屬性值狀態下的結果。
代碼9.1?<c:out>標簽使用示例:coredemo01.jsp
1???? <%@ page pageEncoding="gbk" %>
2???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3???? <html>
4???? <head>
5????????????? <title>out標簽的使用</title>
6???? </head>
7???? <body>
8????????????? <li>(1)<c:out value="北京源智天下科技有限公司"></c:out></li>
9????????????? <li>(2)<c:out value="<未使用字符轉義>" /></li>
10????????????? <li>(3)<c:out value="<使用字符轉義>" escapeXml="false"></c:out></li>
11????????????? <li>(4)<c:out value="${null}">使用了默認值</c:out></li>
12????????????? <li>(5)<c:out value="${null}"></c:out></li>
13???? </body>
14???? </html>
【代碼解析】:
(1)第8行為<c:out>的value屬性賦值為字符串。
(2)第9行和第10行對比,在改變escapeXml屬性后頁面輸出的轉義字符。
(3)第11行value得到null,如果方法體內有值,將輸出方法體中的字符串,否則不輸出,第12行沒有輸出結果。
【代碼解析】:
(1)直接輸出了一個字符串。
(2)字符串中有轉義字符,但在默認情況下沒有轉換。
(3)使用了轉義字符<和>分別轉換成<和>符號。
(4)設定了默認值,從EL表達式${null}得到空值,所以直接輸出設定的默認值。
(5)未設定默認值,輸出結果為空。
2.<c:set>標簽
功能:主要用于將變量存取于JSP范圍中或JavaBean屬性中。
<c:set>標簽的編寫共有4種語法格式。
語法1:存值,把一個值放在指定(page、session等)的map中。
<c:set value=”值1” var=”name1” [scope=”page|request|session|application”]>
含義:把一個變量名為name1值為“值1”的變量存儲在指定的scope范圍內。
語法2:
<c:set var=”name2” [scope=”page|request|session|application”]>
值2
</c:set>
含義:把一個變量名為name2,值為值2的變量存儲在指定的scope范圍內。
語法3:
<c:set value=”值3” target=”JavaBean對象” property=”屬性名”/>
含義:把一個值為“值3”賦值給指定的JavaBean的屬性名。相當與setter()方法。
語法4:
<c:set target=”JavaBean對象” property=”屬性名”>
值4
</c:set>
含義:把一個值4賦值給指定的JavaBean的屬性名。
提示:從共能上分語法1和語法2、語法3和語法4的效果是一樣的只是把value值放置的位置不同至于使用那個根據個人的喜愛,語法1和語法2是向scope范圍內存儲一個值,語法3和語法4是給指定的JavaBean賦值。
【示例代碼】:代碼給出了給指定scope范圍賦值的示例。使用<c:set>標簽把值放入session、application對象中。同時使用EL表達式得到存入的值。
代碼9.2?使用<c:set>存取值:coredemo02.jsp
1???? <%@ page language="java" pageEncoding="gbk"%>
2???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3???? <html>
4???? <head>
5???? <title>set標簽的使用</title>
6???? </head>
7???? <body>
8???? <li>把一個值放入session中。<c:set value="coo" var="name1" scope="session"></c:set>
9???? <li>從session中得到值:${sessionScope.name1 }
10???? <li>把另一個值放入application中。<c:set var="name2" scope="application">olive</c:set>
11????????????? <li>?使用out標簽和EL表達式嵌套得到值:
12???? ???????? <c:out value="${applicationScope.name2}">未得到name的值</c:out></li>
13???? <li>未指定scope的范圍,會從不同的范圍內查找得到相應的值:${name1 }、${name2 }
14???? </body>
15???? </html>
【代碼解析】:
(1)第8行通過<c:set>標簽將值name1的值放入session范圍中。
(2)第9行使用EL表達式得到name1的值。
(3)第10行把name2放入application范圍中。
(4)第11行使用EL表達式從application范圍中取值,用<c:out>標簽輸出使得頁面規范化。
(5)第13行不指定范圍使用EL自動查找得到值。
在代碼中未使用任何Java腳本使用程序的功能。為了對比期間,代碼9.3給出了使用Java腳本實現以上功能的例子。
代碼9.3?Java腳本實現值的存取:getvalue.jsp
1???? <%@page language="java" pageEncoding="gbk"%>
2???? <html>
3???? <head>
4???? <title>set標簽的使用</title>
5???? </head>
6???? <body>
7???? <li>把一個值放入session中。<%session.setAttribute("name1","coo"); %></li>
8???? <li>從session中得到值:<% out.println(session.getAttribute("name1"));?? %></li>
9???? <li>把另一個值放入application中。<% application.setAttribute("name2","olive"); %></li>
10???? <li>?從application中得到值:<% out.println(application.getAttribute("name2")); %></li>
11???? </body>
12???? </html>
【代碼解析】:使用JSP內置對象的方法實現存值和取值的功能。
提示:本章示例為了方便期間都是從一個頁面中存取,在開發中值的存取是為了不同的JSP頁面之間共享數據
從兩個程序對比來看,JSTL實習了使用標簽完成取值賦值的功能,減少代碼的編寫量同時避免了邏輯代碼暴露的危險。
【程序示例】:代碼9.4和代碼9.5演示使用<c:set標簽>操縱JavaBean。
(1)創建一個JavaBean對象。
代碼9.4?JavaBean(vo數據傳輸對象):Person.java
1???? package org.olive;
2???? public class Person {
3???? ???????? private String name;????????????????????????????????????? //定義私有變量姓名字符串
4???? ???????? private int age;?????????????????????????????????????? ???????? //定義私用變量年齡整型
5???? ???????? private char sex;???????????????????????????????????????????? //定義私用變量性別字符性
6???? ???????? private String home;????????????????????????????????????? //定義私用變量家鄉字符串
7???? ???????? public String getName() {???????????????????????????? //name的getter方法
8???? ?????????????????? return name;
9???? ???????? }
10???? ???????? public void setName(String name) {????????? //name的setter方法。
11???? ?????????????????? this.name = name;
12???? ???????? }
13???? ???????? public int getAge() {??????????????????????????????????????? //age的getter方法
14???? ?????????????????? return age;
15???? ???????? }
16???? ???????? public void setAge(int age) {??????????????????????? //age的setter方法
17???? ?????????????????? this.age = age;
18???? ???????? }
19???? ???????? public char getSex() {??????????????????????????????????? //sex的getter方法
20???? ?????????????????? return sex;
21???? ???????? }
22???? ???????? public void setSex(char sex) {????????????????????? //sex的setter方法
23???? ?????????????????? this.sex = sex;
24???? ???????? }
25???? ???????? public String getHome() {???????????????????????????? //home的getter方法
26???? ?????????????????? return home;
27???? }
28???? ???????? public void setHome(String home) {?????????????????? //home的setter方法
29???? ???????? ???????? this.home = home;
30???? ???????? }
31???? }
【代碼解析】:一個只有getter和setter方法的JavaBean或者說一個pojo類,作為一個vo(數據傳輸對象)。定義了四個變量age、name、sex和home。
(2)創建JSP頁面,實現對值的操作。
代碼9.5?操作JavaBean:coredemo03.jsp
1???? <%@ page language="java" pageEncoding="gbk"%>
2???? <jsp:useBean id="person" class="org.olive.Person" />
3???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
4???? <html>
5???? <head>
6???? <title>set標簽的使用</title>
7???? </head>
8???? <body>
9????????????? <c:set target="${person}" property="name">maverick</c:set>
10????????????? <c:set target="${person}" property="age">25</c:set>
11????????????? <c:set target="${person}" property="sex">男</c:set>
12????????????? <c:set target="${person}" property="home">china</c:set>
13????????????? <li>使用的目標對象為:${person }
14????????????? <li>從Bean中獲得的name值為:<c:out value="${person.name}"></c:out>
15????????????? <li>從Bean中獲得的age值為:<c:out value="${person.age}"></c:out>
16????????????? <li>從Bean中獲得的sex值為:<c:out value="${person.sex}"></c:out>
17????????????? <li>從Bean中獲得的home值為:<c:out value="${person.home}"></c:out>
18????????????? </body>
19???? </html>
【代碼解析】:
(1)第1行設置頁面格式和字符編碼集。
(2)第2行使用JSP的指令元素指定要使用的JavaBean。
(3)第3行引入JSTL核心標簽庫。
(4)第9~12行設置JavaBean的屬性值,等同與setter方法。
(5)使用EL表達式得到JavaBean的屬性值,并用out標簽輸出。
【關鍵代碼】:
<jsp:useBean id="person" class="org.olive.Person" />
負責實例化Bean,id指定實例化后的對象名,可以通過${person}得到person在內存中的值(或者使用person.toString()方法)。
<c:set target="${person}" property="name">maverick</c:set>
Target指向實例化后的對象,property指向要插入值的參數名。
注意:使用target時一定要指向實例化后的JavaBean對象,也就是要跟<jsp:useBean>配套使用,也可以java腳本實例化,但這就失去了是用標簽的本質意義。
使用Java腳本實例化:
<%@page import=”org.olive.Person”%
<% Person person=new Person(); %>
3.<c:remove>標簽
<c:remove>標簽主要用來從指定的JSP范圍內移除指定的變量。
【語法】:
<c:remove var=”變量名” [scope=”page|request|session|application”]/>
其中var屬性是必須的,scope可以以省略。
【示例程序】:代碼9.6使用set標簽在session中插入2個值,然后用remove標簽移除。
代碼9.6?<c:remove>標簽示例:coredemo04.jsp
1?????? <%@ page language="java" pageEncoding="gbk"%>
2?????? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3?????? <html>
4?????? <head>
5?????? <title>remove標簽的使用</title>
6?????? </head>
7?????? <body>?
8??????????????? <li><c:set var="name" scope="session">olive</c:set>
9??????????????? <li><c:set var="age" scope="session">25</c:set>
10????????????? <li><c:set var="sex" scope="session">男</c:set>
11????????????? <li><c:out value="${sessionScope.name}"></c:out>
12????????????? <li><c:out value="${sessionScope.age}"></c:out>
13????????????? <li><c:out value="${sessionScope.sex}"></c:out>
14????????????? <li><c:remove var="age"/>
15????????????? <li><c:out value="${sessionScope.name}"></c:out>
16????????????? <li><c:out value="${sessionScope.age}"></c:out>
17????????????? <li><c:out value="${sessionScope.sex}"></c:out>
18????????????? </body>
19 ?? </html>
【代碼解析】:
(1)第8~9行使用set標簽向session中插入三個值:name值為olive、age值為25、sex值為男。
(2)第11~13行使用out和EL表達式輸出name、age、sex的值。
(3)第14行使用remove標簽移除age的值,然后使用步驟第11~13行中的三個輸出作為比較。
4.<c:catch>標簽
用來處理JSP頁面中產生的異常,并將異常信息存儲。
【語法】:
<c:catch var=”name1”>
容易產生異常的代碼
</c:catch>
【參數說明】:
var表示由用戶定義存取異常信息的變量的名稱。省略后也可以實現異常的捕獲,當就不能顯示的輸出異常信息。
【示例代碼】:代碼9.7使用<c:catch></c:catch>標簽,并設計一個異常并輸出異常信息。
代碼9.7?<c:catch>標簽使用示例:coredemo05.jsp
1?????? <%@ page language="java" pageEncoding="gbk"%>
2?????? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3?????? <html>
4?????? <head>
5?????? <title>JSTL: -- catch標簽實例</title>
6?????? </head>
7?????? <body>
8?????? <h4>catch標簽實例</h4>
9?????? <hr>
10????????????? <c:catch ?var=”error”>
11???? <?????? c:set target="Dank" property="hao"></c:set>
12????????????? </c:catch>
13???? <c:out value="${errors}"/>
14???? </body>
15???? </html>
【代碼解析】:
(1)第10~12把容易產生異常的代碼放在<c:catch></c:catch>中,自定義一個變量error用于存儲異常信息。
(2)第11行實現了一段異常代碼,向一個不存在的JavaBean中插入一個值。
(3)第13行用EL表達式得到error的值,并使用<c:out>標簽輸出。
9.2.2?流程控制標簽
流程控制標簽主要用于對頁面簡單業務邏輯進行控制。流程控制標簽包含有4個:<c:if>標簽、<c:choose>標簽、<c:when>標簽和<c:otherwise>標簽。下面將介紹這些標簽的功能和使用方式。
1.<c:if>標簽
<c:if>同程序中的if作用相同,用來實現條件控制。
【語法1】:
<c:if test=”條件1” var=”name” [scope=”page|request|session|application”]>
【語法2】:
<c:if test=”條件2” var=”name”[scope=”page|request|session|application”]>
【參數說明】:
(1)test屬性用于存放判斷的條件,一般使用EL表達式來編寫。
(2)var指定名稱用來存放判斷的結果類型為true或false。
(3)scope用來存放var屬性存放的范圍。
【使用場景】:在開發中經常會出現不同用戶的權限,首先對用戶名進行判斷(包括進行數據庫驗證,該功能可以由JavaBean實現,使用EL表達式得到一個布爾型的結果),把判斷的結果存放在不同的JSP范圍內(比如常用的session內),這樣在每個頁面都可以得到該用戶的權限信息,根據不同權限的用戶顯示不同的結果。
【示例代碼】:代碼9.8實現了用戶輸入用戶名提交到自身頁面,頁面判斷用戶是否為admin,如果是將出現歡迎界面,如果不是顯示不同結果。
代碼9.8?<c:if>標簽使用示例:coredemo06.jsp
1???? <%@ page language="java" pageEncoding="gbk"%>
2???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3???? <html>
4???? <head>
5???? <title>JSTL: -- if標簽示例</title>
6???? </head>
7???? <body>
8????????????? <h4>if標簽示例</h4>
9????????????? <hr>
10????????????? <form action="coredom06.jsp" method="post">
11????????????? <input type="text" name="uname" value="${param.uname}">
12????????????? <input type="submit" value="登錄">
13????????????? </form>
14????????????? <c:if test="${param.uname=='admin' }" var=”adminchock”>
15????????????? <c:out value="管理員歡迎您!">
16????????????? </c:out>
17????????????? </c:if>
18????????????? ${adminchock}
19</body>
20</html>
【代碼解析】:
(1)第10~13行創建一個表單,表單中的元素為一個text文本輸入框,一個提交按鈕,并把信息提交給本頁。
(2)第14行使用if標簽進行判斷,如果輸入的為admin將顯示出定義的字符串,并把檢驗后的結果賦給adminchock,存儲在默認的page范圍中。
(3)第18行使用EL表達式得到adminchock的值,如果輸入的用戶名為admin將顯示true。
提示:可以把adminchock的屬性范圍設置為session,可以在其他的頁面中得到adminchock的值,使用<c:if text=”${adminchock}”><c:if>判斷,實現不同的權限。
2.<c:choose>、<c:when>和<c:otherwise>標簽
這3個標簽通常情況下是一起使用的,<c:choose>標簽作為<c:when>和<c:otherwise>標簽的父標簽來使用。
【語法1】:
<c:choose>
???????? <c:when>
…..//業務邏輯1
???????? <c:otherwise>
…..//業務邏輯2
???????? <c:otherwise>
….//業務邏輯3
</c:choose>
【語法2】:
<c:when text=”條件”>
表達式
</c:when>
【語法3】:
<c:otherwise>
表達式
</c:otherwise>
【參數說明】:
(1)語法1為3個標簽的嵌套使用方式,<c:choose>標簽只能和<c:when>標簽共同使用。
(2)語法2為<c:when>標簽的使用方式,該標簽都條件進行判斷,一般情況下和<c:choose>共同使用。
(3)<c:otherwise>不含有參數,只能跟<c:when>共同使用,并且在嵌套中只允許出現一次。
【示例代碼】:代碼9.9設定一個score變量的值為85,使用嵌套標簽進行判斷,根據判斷返回結果。
代碼9.9?循環控制標簽:coredemo07.jsp
1???? <%@ page language="java" pageEncoding="gbk"%>
2???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3???? <html>
4???? <head>
5????????????? <title>JSTL: -- choose及其嵌套標簽標簽示例</title>
6???? </head>
7???? <body>
8????????????? <h4>choose及其嵌套標簽示例</h4>
9???? <hr>
10????????????? <c:set var="score">85</c:set>
11????????????? <c:choose>
12????????????? c:when test="${score>=90}">
13??????????????你的成績為優秀!
14????????????? </c:when>
15????????????? <c:when test="${score>=70&&score<90}">
16??????????????您的成績為良好!
17????????????? </c:when>
18????????????? <c:when test="${score>60&&score<70}">
19??????????????您的成績為及格
20????????????? </c:when>
21????????????? <c:otherwise>
22??????????????對不起,您沒有通過考試!
23????????????? </c:otherwise>
24????????????? </c:choose>
25????????????? </body>
26???? </html>
【代碼解析】:
(1)第10行通過set標簽設定score的值為85。
(2)第12~22行使用<c:when>進行條件判斷。如果大于等于90,輸出“您的成績為優秀”;
如果大于等于70小于90,輸出“您的成績為良好”;大于等于60小于70,輸出“您的成績為及格”;其他(otherwise)輸出“對不起,您沒能通過考試”。
9.2.3?循環標簽
循環標簽主要實現迭代操作。主要包含兩個標簽:<c:forEach>和<c:forTokens>標簽,接下來將詳細介紹這兩個標簽的用法。
1.<c:forEach>標簽
該標簽根據循環條件遍歷集合(Collection)中的元素。
【語法】:
<c:forEach var=”name” items=”Collection” varStatus=”StatusName” begin=”begin” end=”end” step=”step”>
本體內容
</c:forEach>
【參數解析】:
(1)var設定變量名用于存儲從集合中取出元素。
(2)items指定要遍歷的集合。
(3)varStatus設定變量名,該變量用于存放集合中元素的信息。????
(4)begin、end用于指定遍歷的起始位置和終止位置(可選)。
(5)step指定循環的步長。
參數類型和相關說明見表9-1。
表9-1?循環標簽屬性說明
|   名稱  |   EL  |   類型  |   是否必須  |   默認值  | 
|   var  |   N  |   String  |   是  |   無  | 
|   items  |   Y  |   Arrays Collection Iterator Enumeration Map String []args  |   是  |   無  | 
|   begin  |   Y  |   int  |   否  |   0  | 
|   end  |   Y  |   int  |   否  |   集合中最后一個元素  | 
|   step  |   Y  |   int  |   否  |   1  | 
|   varStatus  |   N  |   String  |   否  |   無  | 
其中varStatus有4個狀態屬性(見表9-2)。
表9-2?varStatus的4個狀態
|   屬性名  |   類型  |   說明  | 
|   index  |   int  |   當前循環的索引值  | 
|   count  |   int  |   循環的次數  | 
|   frist  |   boolean  |   是否為第一個位置  | 
|   last  |   boolean  |   是否為第二個位置  | 
【示例代碼】:代碼9.10實現了遍歷的兩種方式:設定起始位置、不設定起始位置。同時實現了獲得原屬的狀態信息。
代碼9.10?<c:forEach>標簽使用示例:coredemo08.jsp
1???? <%@ page contentType="text/html;charset=GBK" %>
2???? <%@page import="java.util.List"%>
3???? <%@page import="java.util.ArrayList"%>
4???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
5???? <html>
6???? <head>
7????????????? <title>JSTL: -- forEach標簽實例</title>
8???? </head>
9???? <body>
10???? <h4><c:out value="forEach實例"/></h4>
11???? <hr>
12????????????? <%
13?????????????????????? List a=new ArrayList();
14?????????????????????? a.add("貝貝");
15?????????????????????? a.add("晶晶");
16?????????????????????? a.add("歡歡");
17?????????????????????? a.add("瑩瑩");
18???? ?????????????????? a.add("妮妮");
19????????????? request.setAttribute("a",a);
20????????????? %>
21???? ???????? <B><c:out value="不指定begin和end的迭代:" /></B><br>
22 ?? ???????? <c:forEach var="fuwa" items="${a}">
23 ???????????  <c:out value="${fuwa}"/><br>
24????????????? </c:forEach>
25????????????? <B><c:out value="指定begin和end的迭代:" /></B><br>
26????????????? <c:forEach var="fuwa" items="${a}" begin="1" end="3" step="2">
27???? ????????  <c:out value="${fuwa}" /><br>
28????????????? </c:forEach>
29????????????? <B><c:out value="輸出整個迭代的信息:" /></B><br>
30????????????? <c:forEach var="fuwa" items="${a}" begin="3" end="4" step="1" varStatus="s">
31???? ????????  <c:out value="${fuwa}" />的四種屬性:<br>
32???? ????????   所在位置,即索引:<c:out value="${s.index}" /><br>
33???? ????????   總共已迭代的次數:<c:out value="${s.count}" /><br>
34???? ????????   是否為第一個位置:<c:out value="${s.first}" /><br>
35???? ????????   是否為最后一個位置:<c:out value="${s.last}" /><br>
36????????????? </c:forEach>
37???? </body>
38???? </html>
【代碼解析】:
(1)第13~18行通過Java腳本創建了一個集合對象a,并添加元素。
(2)第19行使用setAttribute()方法把集合存入request范圍內。
(3)第22~24行未指定begin和end屬性,直接從集合開始遍歷到集合結束為止。
(4)第26~28行指定從集合的第二個(index值為1)元素開始,到第四個(index值為3)元素截止(index的值從0開始)。并指定step為2即每隔兩個遍歷一次。
(5)第30~35指定varStatus的屬性名為s,并取出存儲的狀態信息。
【總結】:
(1)從圖中可以看到不使用begin和end的迭代,從集合的第一個元素開始,遍歷到最后一個元素。
(2)指定begin的值為1、end的值為3、step的值為2,從第二個開始首先得到晶晶,每兩個遍歷一次,則下一個顯示的結果為瑩瑩,end為3則遍歷結束。
(3)從指定的begin和end的值來看遍歷第四個和第五個,因得到瑩瑩和妮妮。相關狀態信息如圖所示。
提示:本例使用的list是在JSP頁面中使用Java腳本創建的,是因為JSTL缺少創建集合的功能,在開發中一般不會如此,可通過訪問數據庫得到數據集合,和通過設定JavaBean的值得到數據集合
2.<c:forTokens>
該標簽用于瀏覽字符串,并根據指定的字符將字符串截取。
語法:
<c:forTokens items=”strigOfTokens” delims=””delimiters [var=”name” begin=”begin” end=”end” step=”len” varStatus=”statusName”] >
【參數說明】
(1)items指定被迭代的字符串。
(2)delims指定使用的分隔符。
(3)var指定用來存放遍歷到的成員。
(4)begin指定遍歷的開始位置(int型從取值0開始)。
(5)end指定遍歷結束的位置(int型,默認集合中最后一個元素)。
(6)step遍歷的步長(大于0的整型)。
(7)varStatus存放遍歷到的成員的狀態信息。
【示例代碼】:代碼9.11實現了遍歷一個有符號的字符串,把指定的符號移除。指定begin和end值,并獲得遍歷到的元素的狀態信息。
代碼9.11?<c:forTokens>標簽的示例:coredemo09.jsp
1???? <%@ page contentType="text/html;charset=GBK" %>
2???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3???? <html>
4???? <head>
5????????????? <title>JSTL: -- forTokens標簽實例</title>
6???? </head>
7???? <body>
8???? <h4><c:out value="forToken實例"/></h4>
9???? <hr>
10????????????? <c:forTokens items="北、京、歡、迎、您" delims="" var="c1">
11????????????? <c:out value="${c1}"></c:out>
12????????????? </c:forTokens><br>
13????????????? <c:forTokens items="123-4567-8854" delims="-" var="t">
14????????????? <c:out value="${t}"></c:out>
15 ??????????? </c:forTokens><br>
16 ?? <c:forTokens items="1*2*3*4*5*6*7" delims="*" begin="1" end="3" var="n" varStatus="s">
17?????????????  <c:out value="${n}" />的四種屬性:<br>
18???? ????????   所在位置,即索引:<c:out value="${s.index}" /><br>
19???? ????????   總共已迭代的次數:<c:out value="${s.count}" /><br>
20???? ????????   是否為第一個位置:<c:out value="${s.first}" /><br>
21???? ????????   是否為最后一個位置:<c:out value="${s.last}" /><br>
22???? </c:forTokens>
23 ?? </body>
24???? </html>
【代碼解析】:
(1)本示例共實現了3個<c:forToken>循環,10~12行第一個循環實現了遍歷給定字符串“北、京、歡、迎、您”,并除去循環中遇到的“、”號。
(2)13~15行第2個循環遍歷一串帶有分隔符的電話號碼,不讀取分隔符號,將顯示一個字符串。
(3)16~22行第3個循環遍歷一個帶“*”號的字符串,根據指定的起始位置把元素取出,并顯示每個元素的狀態信息。
提示:分隔符的作用是根據標識,截取字符串。如果未設定分隔符或在字符串中沒有找到分隔付,將把整個元素作為一個元素截取。在實際應用中用于在除去某些符號在頁面中顯示。
<c:forToken>的屬性varStatus的使用同<c:forEach>的使用方法相同,在此就再不表述。
9.2.4?URL操作標簽
JSTL包含3個與URL操作有關的標簽,分別為:<c:import>、<c:redirect>和<c:url>標簽。它們的作用為:顯示其他文件的內容、網頁導向、產生URL。下面將詳細介紹這3個標簽的使用方法。
1.<c:import>標簽
該標簽可以把其他靜態或動態文件包含到本JSP頁面。同<jsp:include>的區別為:只能包含同一個web應用中的文件。而<c:import>可以包含其他web應用中的文件,甚至是網絡上的資源。
語法1:
<c:import url=”url” [context=”context”][ value=”value”]
[scope=”page|request|session|application”] [charEncoding=”encoding”]>
語法2:
<c:import url=”url” varReader=”name” [context=”context”][charEncoding=”encoding”]>
主要參數見表9-3。
表9-3?<c:import>標簽參數說明
|   名稱  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   url  |   被導入資源的URL路徑  |   Y  |   String  |   是  |   無  | 
|   context  |   相同服務器下其他的web工程,必須以“"”開頭  |   Y  |   String  |   否  |   無  | 
|   var  |   以String類型存入被包含文件的內容。  |   N  |   String  |   否  |   無  | 
|   Scope  |   var變量的JSP范圍  |   N  |   String  |   否  |   page  | 
|   charEncoding  |   被導入文件的編碼格式  |   Y  |   String  |   否  |   無  | 
|   varReader  |   以Reader類型存儲被包含文件內容  |   N  |   String  |   否  |   無  | 
【參數說明】:
(1)URL為資源的路徑,當應用的資源不存在時系統會拋出異常,因此該語句應該放在<c:catch></c:catch>語句塊中捕獲。應用資源有兩種方式:絕對路徑和相對路徑。使用絕對路徑示例如下:
<c:import url=”http://www.baidu.com”>
使用相對路徑的實例如下:
<c:import url=”aa.txt”>
aa.txt放在同一文件目錄。
如果以“/”開頭表示應用的根目錄下。例如:tomcat應用程序的根目錄文件夾為webapps。導入webapps下的文件bb.txt的編寫方式為:
<c:import url=”/bb.txt”>
如果訪問webapps管理文件夾中其他web應用就要用context屬性。
(2)context屬性用于在訪問其他web應用的文件時,指定根目錄。例如,訪問root下的index.jsp的實現代碼為:
<c:import url=”/index.jsp” context=”/root”>
等同于webapps/root/index.jsp
(3)var、scope、charEncoding、varReader是可選屬性。具體使用方式見示例代碼。
【示例代碼】:代碼9.12實現了從絕對路徑導入文件和從相對路徑導入,同時使用var對象指定用變量來存儲文件,并輸出存入的文件內容。
代碼9.12?<c:import>標簽示例:coredemo10.jsp
1???? <%@ page contentType="text/html;charset=GBK" %>
2???? <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3???? <html>
4???? <head>
5????????????? <title>JSTL: -- import標簽實例</title>
6???? </head>
7???? <body>
8???? <h4><c:out value="import實例"/></h4>
9???? <hr>
10???? <h4><c:out value="絕對路徑引用的實例" /></h4>
11???? <c:catch var="error1">
12???? <c:import url="http://www.baidu.com"/>
13 ?? </c:catch>
14 ?? <c:out value="${error1}"></c:out>
15 ?? <hr>
16???? <h4>
17???? <c:out value="相對路徑引用的實例,引用本應用中的文件" /></h4>
18???? <c:catch>
19???? <c:import url="a1.txt" charEncoding="gbk"/>
20???? </c:catch>
21???? <hr>
22???? <h4><c:out value="使用字符串輸出、相對路徑引用的實例,并保存在session范圍內" /></h4>
23???? <c:catch var="error3">
24???? <c:import var="myurl" url="a1.txt" scope="session" charEncoding="gbk"></c:import>
25???? <c:out value="${myurl}"></c:out>
26???? <c:out value="${myurl}" />
27???? </c:catch>
28???? <c:out value="${error3}"></c:out>
29???? </body>
30???? </html>
【代碼解析】:
(1)第12行使用絕對路徑導入百度首頁,導入時使用<c:catch></c:catch>(11和12行)捕獲異常。
(2)使用相對路徑導入同一文件夾下的a1.txt文件,接收的字符編碼格式使用charEncoding設置為gbk。
(3)同樣導入a1.txt,不同的時使用var定義的變量接收要導入的文件,并存儲在session中,如果在其他頁面同樣也要導入該文件,只須使用<c:out>輸出a1.txt的值即可。
【說明】:
(1)在使用絕對路徑導入時,因為電腦沒有聯網所以拋出異常。
(2)使用相對路徑輸出時,同樣是引入的a1.txt文件顯示的結果卻不相同,這可以說明直接使用<c:import>導入,不設定var參數是直接在頁面中顯示的文本信息。而使用var參數輸出時輸出的實現存入的字符串。
提示:讀者在練習時可以使用Tomcat的首頁來導入url=”http://127.0.0.1:8080”來顯示效果。
2.<c:redirect>標簽
該標簽用來實現了請求的重定向。同時可以在url中加入指定的參數。例如:對用戶輸入的用戶名和密碼進行驗證,如果驗證不成功重定向到登錄頁面;或者實現web應用不同模塊之間的銜接。
【語法1】:
<c:redirect url=”url” [context=”context”]>
【語法2】:
<c:redirect url=”url”[context=”context”]>
<c:param name=”name1” value=”value1”>
</c:redirect>
【參數說明】:
(1)url指定重定向頁面的地址,可以是一個string類型的絕對地址或相對地址。
(2)用于導入其他web應用中的頁面。
【示例代碼】:代碼9.13實現了當請求頁面時重定向到tomcat首頁。
代碼9.13?<c:redirect>標簽示例:coredemo11.jsp
<%@ page contentType="text/html;charset=GBK" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:redirect url="http://127.0.0.1:8080">
<c:param name="uname">olive</c:param>
<c:param name="password">01234</c:param>
</c:redirect>
【代碼解析】
(1)使用重定向與載入頁面不同,載入頁面時在本頁面中插入其他頁面,而重定向是請求轉發,等于在頁面中重新輸入了一次url。當重定向到某個頁面時瀏覽器中的地址會發生變化。
(2)使用重定向時不用使用<c:catch>語句,當輸入頁面訪問不到時,瀏覽器會報錯,跟程序運行無關。如果使用重定向時頁面定義的內容將不會得到顯示。
(3)在重定向時為URL添加了兩個參數和參數值:uname=olive和password=01234。
提示:注意圖中的URL地址已經發生轉變,同時可以看到傳入的參數以參數值。
3.<c:url>標簽
該標簽用于動態生成一個String類型的URL,可以同<c:redirect>標簽共同使用,也可以使用html的<a>標簽實現超鏈接。
【語法1】:指定一個url不做修改,可以選擇把該url存儲在JSP不同的范圍中。
<c:url value=”value” [var=”name”][scope=”page|request|session|application”]
[context=”context”]/>
【語法2】:給url加上指定參數及參數值,可以選擇以name存儲該url。
<c:url value=”value” [var=”name”][scope=”page|request|session|application”]
[context=”context”]>
<c:param name=”參數名”?value=”值”>
</c:url>
【示例代碼】:代碼9.14實現了使用動態生成url實現了網頁的超鏈接。
代碼9.14?<c:url>標簽示例:coredemo12.jsp
<%@ page contentType="text/html;charset=GBK" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out value="url標簽使用"></c:out>
<h4>使用url標簽生成一個動態的url,并把值存入session中.</h4>
<hr>
<c:url value="http://127.0.0.1:8080" var="url" scope="session">
</c:url>
<a href="${url}">Tomcat首頁</a>
9.3?I18N格式標簽庫
JSTL標簽提供了對國際化(I18N)的支持,它可以根據發出請求的客戶端地域的不同來顯示不同的語言。同時還提供了格式化數據和日期的方法。實現這些功能需要I18N格式標簽庫(I18N-capable formation tags liberary)。引入該標簽庫的方法為:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
I18N格式標簽庫提供了11個標簽,這些?標簽從功能上可以劃分為3類如下:
(1)數字日期格式化。formatNumber標簽、formatData標簽、parseNumber標簽、parseDate標簽、timeZone標簽、setTimeZone標簽。
(2)讀取消息資源。bundle標簽、message標簽、setBundle標簽。
(3)國際化。setlocale標簽、requestEncoding標簽。
接下將詳細介紹這些標簽的功能和使用方式。
9.3.1?數字日期格式化
數字日期格式化標簽共有6個,用來將數字或日期轉換成設定的格式。
1.<frm:formatNumber/>標簽
該標簽依據特定的區域將數字改變為不同的格式來顯示。
【語法1】:
<frm:formatNumber value=”被格式化的數據”[type=”number|currency|percent”]
?????????????????????????????????????????????? [pattern=”pattern”]
?????????????????????????????????????????????? [currencyCode=”code”]
?????????????????????????????????????????????? [currencySymbol=”symbol”]
?????????????????????????????????????????????? [groupingUsed=”true|false”]
?????????????????????????????????????????????? [maxIntergerDigits=”maxDigits”]
?????????????????????????????????????????????? [minIntergerDigits=”minDigits”]
?????????????????????????????????????????????? [maxFractionDigits=”maxDigits”]
?????????????????????????????????????????????? [minFractionDigits=”minDigits”]
?????????????????????????????????????????????? [var=”name”]
?????????????????????????????????????????????? [scope=page|request|session|application]
/>
【語法2】:
<frm:formatNumber [type=”number|currency|percent”]
?????????????????????????????????????????????? [pattern=”pattern”]
?????????????????????????????????????????????? [currencyCode=”code”]
?????????????????????????????????????????????? [currencySymbol=”symbol”]
?????????????????????????????????????????????? [groupingUsed=”true|false”]
?????????????????????????????????????????????? [maxIntergerDigits=”maxDigits”]
?????????????????????????????????????????????? [minIntergerDigits=”minDigits”]
?????????????????????????????????????????????? [maxFractionDigits=”maxDigits”]
?????????????????????????????????????????????? [minFractionDigits=”minDigits”]
?????????????????????????????????????????????? [var=”name”]
?????????????????????????????????????????????? [scope=page|request|session|application]
>?
被格式化的數據
<frm:formatNumber>
屬性說明如表9-4所示。
表9-4?<fmt:formatNumber>標簽參數說明
|   名稱  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   value  |   要格式化的數據  |   是  |   String  |   是  |   無  | 
|   type  |   指定類型(單位、貨幣、百分比等)見表  |   是  |   String  |   否  |   number  | 
|   pattern  |   格式化的數據樣式  |   是  |   String  |   否  |   無  | 
|   currencyCode  |   貨幣單位代碼  |   是  |   String  |   否  |   無  | 
|   cuttencySymbol  |   貨幣符號($、¥)  |   是  |   String  |   否  |   無  | 
|   groupingUsed  |   是否對整數部分進行分組如(9,999)  |   是  |   boolean  |   是  |   true  | 
|   maxIntergerDigits  |   整數部分最對顯示多少位數  |   是  |   int  |   否  |   無  | 
|   minIntergerDigits  |   整數部分最少顯示多少位  |   是  |   int  |   否  |   無  | 
|   maxFractionDigits  |   小數部分最多顯示多少位  |   是  |   int  |   否  |   無  | 
|   minFractionDigits  |   小數部分最少顯示多少位  |   是  |   int  |   否  |   無  | 
|   var  |   存儲格式化后的數據  |   否  |   String  |   否  |   無  | 
|   scope  |   var的JSP范圍  |   否  |   String  |   否  |   page  | 
Type屬性的類型應用見表9-5.
表9-5?Type的屬性類型
|   類型  |   說明  |   示例  | 
|   number  |   數字格式  |   0.8  | 
|   currency  |   當地貨幣  |   ¥0.80  | 
|   percent  |   百分比格式  |   80%  | 
【示例代碼】:代碼9.14實現了對數字的格式化、貨幣的格式、貨幣的格式化。使用<frm:formatNumber>的各種屬性的設定。
代碼9.14?<fmt:formatNumber>標簽示例:fmtdemo01.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
?<head>?????
??? <title>I18N標簽庫</title>
?</head>
?<body>
?<h4 align="center"><c:out value="<frm:number>標簽的使用"></c:out></h4>
?<hr>
?<table border=1 cellpadding="0" cellspacing="0" align="center">
?<tr align="center">
<td width="100">類型?</td>
<td width="100">使用數據</td>
<td width="100">結果</td>
<td width="300">說明</td>
?</tr>
?<tr>
?<td>數字格式化</td><td>108.75</td>
?<td><fmt:formatNumber type="number" pattern="###.#">108.75</fmt:formatNumber></td>
?<td>使用pattern可以定義顯示的樣式。本例設定為###.#小數部分將使用四舍五入法。</td>
?</tr>
?<tr>
?<td>數字格式化</td><td>9557</td>
?<td><fmt:formatNumber type="number" pattern="#.####E0">9557</fmt:formatNumber></td>
?<td>使用科學計數法。</td>?
?</tr>
?<tr>
?<td>數字格式化</td><td>9557</td>
?<td><fmt:formatNumber type="number" >9557</fmt:formatNumber></td>
?</td>
?<td>使用默認分組。</td>
?</tr>
?<tr>
?<td>數字格式化</td><td>9557</td>
?<td><fmt:formatNumber type="number" groupingUsed="false" >9557</fmt:formatNumber></td>
?<td>不使用分組。</td>
?</tr>
?<tr>
?<td>數字格式化</td><td>9557</td>
?<td><fmt:formatNumber type="number" maxIntegerDigits="3">9557</fmt:formatNumber></td>
?<td>使用位數限定,根據指定的位數顯示,其他數字忽略。例如:9不被顯示。</td>
?</tr>
?<tr>
?<td>百分比格式化</td><td>0.98</td>
?<td><fmt:formatNumber type="percent">0.98</fmt:formatNumber></td>
?<td>用百分比形式顯示一個數據。</td>
?</tr>
?<tr>
?<td>貨幣格式化</td><td>188.88</td>
?<td><fmt:formatNumber type="currency" >188.8</fmt:formatNumber></td>
<td>將一個數據轉化為貨幣形式輸出。</td>
?</tr>
?<tr>
?<td>存儲數據</td><td>188.88</td>
?<td><fmt:formatNumber type="currency" var="money">188.8</fmt:formatNumber>
?<c:out value="${money}"></c:out>
?</td>
?<td>存儲的money的值為${money} </td>
?</tr>
?</table>
?</body>
</html>
【代碼說明】:
(1)從應用角度可以把屬性分為三類:數字格式化、貨幣格式化、百分比格式化。使用type指定類型。
(2)應用于數字格式化的屬性有:partten屬性、maxIntegerDigits屬性、minIntegerDigits屬性、maxFractionDigits屬性和minFactionDigits屬性。其中partten屬性在設定格式化樣式時會比較準確如:四舍五入、科學計數法的使用。而使用maIntegerDirgits等屬性時,只把設定位數以外的數字舍去。
(3)貨幣格式化可以使用數字格式化的所有屬性。如果有必要建議使用partten屬性。currencyCode屬性和currencySymbol只用于貨幣格式化。
(4)百分比格式化使用到的屬性為type屬性、partten屬性,設定type屬性的類型為percent即可。
(5)使用var屬性時,會將格式化后的值存在JSP的某個范圍內(一個String類型的字符串包括符號等)。<frm:forNumber>將不再輸出格式化后的值可以使用EL表達式輸出。
(6)通用屬性:type屬性、partten屬性、var屬性和scope屬性。
提示:如果給定的數據類型有錯誤將或產生異常。例如:給定的數據為aa進行類型轉化,將使應用程序無法顯示。因此在實際應用中顯示的格式化應該放入<c:catch/>語句中。
2.<frm:parseNumber>標簽
將格式化后的數字、貨幣、百分比都轉化為數字類型。
【語法1】:
<fmt:parseNumber value="number" [type=”number|currency|percent”]
??????????????????????????????????????????????????????? [pattern=”pattern”]
??????????????????????????????????????????????????????? [parseLocale=”locale”]???????????????????????
??????????????????????????????????????????????????????? [intergerOnly=”true|false”]
??????????????????????????????????????????????????????? [scope=”page|request|session|application”]
/>
【語法2】:
<fmt:parseNumber [type=”number|currency|percent”]
??????????????????????????????????????????????????????? [pattern=”pattern”]
??????????????????????????????????????????????????????? [parseLocale=”locale”]
??????????????????????????????????????????????????????? [intergerOnly=”true|false”]
??????????????????????????????????????????????????????? [scope=”page|request|session|application”]
>?
Number
</fmt:parseNumber>
屬性說明見表9-6。
表9-6?<fmt:parseNumber>標簽參數說明
|   名稱  |   說明  |   EL  |   類型  |   是否必須  |   默認值  | 
|   value  |   被解析的字符串  |   是  |   String  |   是  |   無  | 
|   type  |   指定單位(數字、貨幣、百分比)  |   是  |   String  |   是  |   number  | 
|   pattern  |   格式樣式  |   是  |   String  |   否  |   無  | 
|   parseLocale  |   用來替代默認區域的設定  |   是  |   String, Java.util. Locale  |   是  |   默認本地樣式  | 
|   var  |   存儲已經格式化的數據  |   否  |   String  |   否  |   無  | 
|   scope  |   var變量的作用域  |   否  |   String  |   是  |   page  | 
<fmt:parseNumber>可以看作是<fmt:formatNumber>的逆運算。相應的參數和類型的配置和使用<fmt:formatNumber>格式化時相同。
【示例代碼】:代碼9.15實現了從字符串中提取數據,并用合適的數據類型進行存儲(浮點性、整型等)。可以對轉換后的數據進行加法運算。
代碼9.15?<fmt:parseNumber>標簽示例:fmtdemo02.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
?<head>
?<title>I18N標簽庫</title>
?</head>
?<body>
?<h4 ><c:out value="<frm:parseNumber>標簽的使用"></c:out></h4>
?<hr>
?</body>
?<fmt:formatNumber type="currency" var="money">188.8</fmt:formatNumber>
?<li>格式化前的數據為:<c:out value="${money}"></c:out>
?<fmt:parseNumber var="money" type="currency">${money}</fmt:parseNumber>
?<li>格式化后的數據為:<c:out value="${money}"></c:out>
?<li>可以對格式化的后的數據進行運算:?
?<c:out value="${money+200}"></c:out>
?<li>對百分比進行格式化98%為:
?<fmt:parseNumber type="percent">98%</fmt:parseNumber>
</html>
【代碼解析】:
(1)首先使用<fmt:formatNumber>將188.8轉換為字符串¥188.8并在page范圍內存儲一個String類型的變量,變量名為money。
(2)使用<fmt:parseNumber>將¥188.8轉化為浮點型的數據188.8并賦值為變量money,
則變量money轉變為一個浮點型的值188.8,對188.8進行加運算。
(3)直接對一個百分比數98%進行轉化。
提示:<fmt:parseNumber>屬性參數的配置和使用同<fmt:formatNumber>標簽使用的方式一樣。同時,在進行類型轉換時如果給出的類型不正確將會出現異常。例如在進行百分比轉化時如果沒有給type類型或者給出type類型但提供的數據中沒有%都會產生異常。因此在實際應用中用<c:catch/>捕獲異常。
<fmt:formatNumber value="12" type="currency" pattern="$.00"/> -- $12.00
<fmt:formatNumber value="12" type="currency" pattern="$.0#"/> -- $12.0
<fmt:formatNumber value="1234567890" type="currency"/> -- $1,234,567,890.00(那個貨幣的符號和當前web服務器的 local 設定有關)
<fmt:formatNumber value="123456.7891" pattern="#,#00.0#"/> -- 123,456.79
<fmt:formatNumber value="123456.7" pattern="#,#00.0#"/> -- 123,456.7
<fmt:formatNumber value="123456.7" pattern="#,#00.00#"/> -- 123,456.70
<fmt:formatNumber value="12" type="percent" /> -- 1,200% (type 可以是currency、 number、 和percent)。
java格式化輸出:
DecimalFormat df = new DecimalFormat("格式");
String fmt =df.format(double);
符號??????????????????意義
0?????????????????????一個數位
#?????????????????????一個數位,前導零和追尾零不顯示
.??????????????????????小數點分割位置
,?????????????????????組分隔符的位置
-??????????????????????負數前綴
%????????????????????用100乘,并顯示百分號
其他任何符號????在輸出字符串中包括指定符號
數字用例:<fmt:formatNumber value="${order.orderAmount}" minFractionDigits="2"/>元
3.<fmt:formatDate>標簽
該標簽主要用來格式化日期和時間。
【語法】:
<fmt: formatDate value=”date” [type=”time|date|both”]
???????????????????????????????????? [pattern=”pattern”]
???????????????????????????????????? [dateStyle=”default|short|medium|long|full”]
???????????????????????????????????? [timeStyle=”default|short|medium|long|full”]
???????????????????????????????????? [timeZone=”timeZone”]
???????????????????????????????????? [var=”name”]
???????????????????????????????????? [scope=”page|request|session|application”]
/>
參數說明見表9-7。
表9-7?<fmt:formatDate>標簽屬性說明
|   屬性名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   value  |   將要格式化的日期對象。  |   是  |   Java.util.Date  |   是  |   無  | 
|   type  |   顯示的部分(日期、時間或者兩者)。  |   是  |   String  |   否  |   date  | 
|   partten  |   格式化的樣式。  |   是  |   String  |   否  |   無  | 
|   dateStyle  |   設定日期的顯示方式。  |   是  |   String  |   否  |   default  | 
|   timeStyle  |   設定時間的顯示方式。  |   是  |   String  |   否  |   default  | 
|   timeZone  |   設定使用的時區。  |   是  |   String  |   否  |   當地所用時區  | 
|   var  |   存儲已格式化的日期或時間。  |   否  |   String  |   否  |   無  | 
|   scope  |   指定var存儲的JSP范圍。  |   否  |   String  |   否  |   無  | 
其中type屬性參數說明見表9-8。
表9-8?type屬性參數說明
|   參數名  |   說明  | 
|   time  |   只顯示時間  | 
|   date  |   只顯示時期  | 
|   both  |   顯示日期和時間  | 
【示例程序】:代碼9.16實現了對日期的格式化,使用了type、dateStyle、timeStyle等屬性。
代碼9.16?<fmt:formatDate>標簽示例:fmtdemo03.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date"></jsp:useBean>
<html>
?<head>??
??? <title>I18N標簽庫</title>
?</head>
?<body>
<fmt:formatDate value="${date}"></fmt:formatDate><br>
<fmt:formatDate value="${date}" type="both"></fmt:formatDate><br>
<fmt:formatDate value="${date}" type="both" dateStyle="default"
?timeStyle="default"></fmt:formatDate><br>
?? <fmt:formatDate value="${date}" type="both" dateStyle="short"
?timeStyle="short"></fmt:formatDate><br>
?? <fmt:formatDate value="${date}" type="both" dateStyle="long"
?timeStyle="long"></fmt:formatDate><br>
?? <fmt:formatDate value="${date}" type="both" dateStyle="full"
timeStyle="full"></fmt:formatDate><br>
?? <fmt:formatDate value="${date}" type="both" dateStyle="full"
timeStyle="full"></fmt:formatDate><br>
?? </body>
</html>
【代碼解析】:
(1)首先通過配置JavaBean在頁面上實例化java.util.Date對象。實現代碼如下:
<jsp:useBean id="date" class="java.util.Date"></jsp:useBean>
(2)對日期對象進行格式化時${date}是一個日期對象,如果給value設的值為String時程序會報錯。
(3)設置type為both時,將顯示日期和時間,同時示例中依次改變dateStyle和timeStyle的值作為比較。
4.<fmt:parseDate>標簽
<fmt:parseDate>標簽主要將字符串類型的時間或日期轉化為時間或日期對象。
【語法1】:
<fmt:parseDate value=”date” [type=”time|date|both”]
??????????????????????????????????????????????????????? [pattern=”pattern”]
??????????????????????????????????????????????????????? [parseLocale=”locale”]
??????????????????????????????????????????????????????? [dateStyle=”default|short|medium|long|full”]
??????????????????????????????????????????????????????? [timeStyle=”default|short|medium|long|full”]
??????????????????????????????????????????????????????? [timeZone=”timezone”]
??????????????????????????????????????????????????????? [var=”name”]
??????????????????????????????????????????????????????? [scope=”page|request|session|application”]
/>
【語法2】:
<fmt:parseDate?[type=”time|date|both”]
??????????????????????????? ??????????????????????????? [pattern=”pattern”]
??????????????????????????????????????????????????????? [parseLocale=”locale”]
??????????????????????????????????????????????????????? [dateStyle=”default|short|medium|long|full”]
??????????????????????????????????????????????????????? [timeStyle=”default|short|medium|long|full”]
??????????????????????????????????????????????????????? [timeZone=”timezone”]
??????????????????????????????????????????????????????? [var=”name”]
??????????????????????????????????????????????????????? [scope=”page|request|session|application”]
>?
Date
</fmt:parseDate>
【參數說明】參數說明見表9-9.
表9-9?<fmt:parseData>標簽屬性說明
|   屬性名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   value  |   將要格式化的日期時間  |   是  |   String  |   是  |   無  | 
|   type  |   字符串的類型(日期、時間或全部)  |   EL  |   String  |   是  |   date  | 
|   pattern  |   字符串使用的時間樣式  |   是  |   String  |   是  |   無  | 
|   parseLocale  |   取代默認地區設定  |   是  |   String  |   是  |   默認地區  | 
|   dateStyle  |   字符串使用的日期顯示方式  |   是  |   String  |   否  |   default  | 
|   timeStyle  |   字符串使用的時間顯示格式  |   是  |   String  |   否  |   default  | 
|   timeZone  |   使用的時區  |   是  |   String  |   否  |   當地區時  | 
|   var  |   使用var定義的名字保存對象  |   否  |   String  |   否  |   無  | 
|   scope  |   var的JSP范圍  |   否  |   String  |   否  |   page  | 
【示例代碼】:代碼9.16實現了以下功能:首先,使用了<fmt:formatDate>把一個日期對象格式化成一個日期的字符串,并把該字符串以參數名為a存儲page范圍內。其次,使用<fmt:parseDate>方法把a的值(字符串)格式化成一個Date并以參數名為b存儲在page范圍內。最后,使用Java腳本證明生成的b為對象。
代碼9.16:<fmt:formatDate>標簽示例:fmtdemo04.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date"></jsp:useBean>
<html>
?<head>??
??? <title>I18N標簽庫</title>
?</head>
?<body>
?? <H4><c:out value="<frm:parseDate>標簽的使用"></c:out></H4>
?? <hr>
<fmt:formatDate value="${date}" var="a" type="both"
dateStyle="full" timeStyle="full"></fmt:formatDate>
<fmt:parseDate var="b" type="both" dateStyle="full" timeStyle="full">
${a}
</fmt:parseDate>
?? <%
?? out.println(pageContext.getAttribute("b").toString());
?? out.println("<br>");
?? out.println(pageContext.getAttribute("b").hashCode());
?? %>
?? </body>
</html>
【代碼解析】:
(1)使用<fmt:formatDate>把日期對象格式化成字符串。
(2)使用<fmt:parseDate>把字符串對象轉化為日期對象,注意同(1)中的參數對比,可以發現兩者是一個互逆的過程。
(3)使用Java腳本進行測試Date對象的toString()方法可以輸出時間字符串。hashCode()可以得到一個對象的hashCode。該方法只能應用于對象,因此可以證明得到的是一個日期對象。
提示:<fmt:formatDate>和<fmt:parseDate>是相反的運算過程,可以對照學習。本例中的Java腳本的作用是為了證明生成的的確是一個對象。
5.<fmt:setTimeZone>標簽
該標簽用于設定默認時區或者將時區存儲在指定的JSP范圍內。
【語法】:
<fmt:setTimeZone value=”value” [var=”name”][scope=”page|request|session|application”]/>
【參數說明】:見表9-10
表9-10?<fmt:setTimeZone>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   value  |   使用的時區  |   是  |   String Java.util.TimeZone  |   是  |   無  | 
|   var  |   使用var定義的參數名保存值  |   否  |   String  |   否  |   無  | 
|   scope  |   存儲var的JSP范圍  |   否  |   String  |   否  |   page  | 
value用來設定使用的時區,例如中國使用的時區為CST,其他的還有EST、PST等。可以把時區存儲在指定的JSP范圍內,例如存儲在session中,用戶訪問的所有頁面都可以顯示使用的設定的時區下對應的時間。
【示例代碼】
<fmt:setTimeZone value=”EST” scope=”session”/>
提示:有關TimeZone的說明見JDK幫助文檔的java.util.TimeZone類。
6.<fmt:timeZone>標簽
該標簽主要用于設置標簽體內使用的時區。
【語法】:
<fmt:timeZone value=”timeZone”>
…..
</fmt:timeZone>
使用<fmt:timeZone></fmt:timeZone>只會應用到標簽體內使用的時區,對標簽外部將不產生影響。
9.3.2?讀取消息資源
讀取消息資源用到的標簽主要有4個:<fmt:message>標簽、<fmt:param>標簽、<fmt:bundle>標簽和<fmt:setBundle>標簽。主要用于從資源文件中讀取信息。
1.<fmt:bundle>標簽
該標簽主要用于將資源文件綁定于它的標簽體中的顯示。
【語法】:
<fmt:bundle basename=”name”[prefix=”prefix”]>
….標簽主題
</fmt:bundle>
【參數說明】:見表9-11。
表9-11?<fmt:bundle>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   basename  |   指定使用的資源文件的名稱  |   是  |   String  |   是  |   無  | 
|   prefix  |   前置關鍵字  |   是  |   String  |   否  |   無  | 
2.<fmt:setBundle>標簽
該標簽主要用于綁定資源文件或者把資源文件保存在指定的JSP范圍內。
【語法】:
<fmt:setBundle basename=”name” [var=”name”]
???????????????????????????????????? [scope=”page|request|session|application”]
>?
【參數說明】:見表9-12。
表9-12?<fmt:setBundle>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   basename  |   指定使用的資源文件的名稱  |   是  |   String  |   是  |   無  | 
|   var  |   指定將資源文件保存的名稱  |   否  |   String  |   否  |   無  | 
|   scope  |   設定將資源文件保存的JSP范圍  |   否  |   String  |   否  |   page  | 
3.<fmt:message>標簽
該標簽主要負責讀取本地資源文件,從指定的消息文本資源文件中讀取鍵值,并且可以將鍵值保存在指定的JSP范圍內。
【語法1】:
<fmt:message key=”keyName”[bundle=”bundle”]
???????????????????????????????????? [scope=”page|request|session|application”]
/>
【語法2】:
<fmt:message key=”keyName”[bundle=”bundle”]
???????????????????????????????????? [scope=”page|request|session|application”]
>?
<fmt:param/>
</fmt:message>
【語法3】:
<fmt:message key=”keyName”[bundle=”bundle”]
??????????????????????????????????????????????????????? [scope=”page|request|session|application”]
>?
key<fmt:param/>
…
</fmt:message>
【參數說明】:見表9-13。
表9-13?<fmt:message>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   key  |   指定鍵值的名稱(索引)  |   是  |   String  |   是  |   無  | 
|   bundle  |   指定消息文本的來源  |   是  |   LocalizationContext  |   否  |   無  | 
|   var  |   指定存儲鍵值的變量名  |   否  |   String  |   否  |   無  | 
|   scope  |   指定var的作用域  |   否  |   String  |   否  |   page  | 
提示:建議此處的bundle使用EL表達式,因為屬性bundle的類型為LocalizationContext,而不是一個String類型的URL。
【示例代碼】:代碼9.17實現從指定的資源文件中讀取對應key的值。
首先編寫一個資源文件內容下
name=olive
password=01234
使用標簽從資源文件中讀取相應的值。
代碼9.17?<fmt:message>標簽示例:fmtdemo05.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date"></jsp:useBean>
<html>
?<head>??
??? <title>I18N標簽庫</title>
?</head>
?<body>
?? <H4><c:out value="資源文件讀取示例"></c:out></H4>
?? <hr>
?? <fmt:bundle basename="message">
?? <c:out value="從message資源文件中得到的key為name的值為:"></c:out>
?? <fmt:message key="name" ></fmt:message>
?? </fmt:bundle>
?? <hr>
?? <fmt:setBundle basename="message" var="m"/>
?? <fmt:message key="password" bundle="${m}"></fmt:message>
??? ${m}
?? </body>
</html>
【代碼解析】:
(1)使用<fmt:bundle>標簽指定從message.properties文件中讀取值。
(2)使用<fmt:message>標簽讀取資源文件中key為name的值。<fmt:message>標簽放在<fmt:bundle>標簽體內使用。
(3)使用<fmt:setBundle>標簽在page范圍綁定一個配置文件,以m為參數名存儲。
(4)使用<fmt:message>標簽得到key為password的值,此處指定資源文件的方式為使用<fmt:message>標簽的bundle屬性來設定。
(5)輸出參數m的值,加深對bundle的理解。
<fmt:bundle>標簽中有一個prefix屬性,該標簽用來指明前綴。例如配置文件內容如下:
org.person.name=olive
org.personpassword=01234
如果不使用prefix標簽,在取值是要指明前綴。例如:
<fmt:bundle basename=”message”>
<fmt:message key=”org.person.name”></fmt:message>
<fmt:message key=”org.person.password”></fmt:message>
</fmt:bundle>
使用prefix屬性可以簡化取值時的代碼。
<fmt:bundle basename=”message” prefix=”org.person”>
<fmt:message key=”name”></fmt:message>
<fmt:message key=”password”></fmt:message>
</fmt:bundle>
4.<fmt:param>標簽
該標簽主要用于當<fmt:message>中資源文件中獲得鍵值時,動態的為資源文件中的變量賦值。
【語法1】:
<fmt:param value=”value”/>
【語法2】:
<fmt:param >
…標簽主體
</fmt:param>
【示例代碼】:
(1)創建資源文件。在message.properties文件中增加一個key和value。
news={0}?welcome to out website!<br>today is :{1,date}
表達的含義是鍵news對應的是一個字符串,字符串中還有動態變量{0}表示第一個動態變量,{1,date}表示第二個動態變量并且該變量是一個日期類型的對象。
(2)通過標簽從資源文件中取出鍵值,并給動態變量賦值顯示在頁面。
代碼9.18?<fmt:param>標簽示例:fmtdemo06.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date"></jsp:useBean>
<html>
?<head>??
??? <title>I18N標簽庫</title>
?</head>
?<body>
?? <H4><c:out value="<fmt:param>標簽的使用"></c:out></H4>
?? <hr>
?? <fmt:bundle basename="message">
?? <fmt:message key="news">
?? <fmt:param value="olive" />
?? <fmt:param value="${date}"/>
?? </fmt:message>
?? </fmt:bundle>
?? </body>
</html>
【代碼解析】:
(1)使用<fmt:bundle>標簽把資源文件綁定在標簽體內。
(2)在<fmt:bundle>標簽體內使用<fmt:message>得到鍵值。
(3)使用<fmt:param>為資源文件中的動態變量賦值。
提示:資源文件經過修改后,應用程序需要重載才能生效。
9.3.3?國際化
國際化這個分類中共包含兩個標簽:用于設定語言地區<fmt:setLocale/>和用于設定請求的字符編碼的<fmt:requestEncoding>標簽。
1.<fmt:setLocale/>標簽
<fmt:setLocale>標簽用來設定用戶語言區域。
【語法】:
<fmt:setLocale value=”locale”[variant=”variant”]
??????????????????????????? [scope=”page|request|session|application”]>
【參數說明】:見表9-14。
表9-14?<fmt:setLocale>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   value  |   指定區域代碼  |   是  |   String java.util.Locale  |   是  |   無  | 
|   variant  |   操作系統的類型  |   是  |   String  |   是  |   無  | 
|   scope  |   設定時區的作用范圍  |   否  |   String  |   是  |   page  | 
value屬性用來指定使用的語言代碼,可以從瀏覽器的【工具】---【Internet選項】---【語言】---【添加】中查看瀏覽器支持的語言種類及語言代碼。例如:中文(zh_cn)、臺灣(zh_tw)、香港(zh_mo)等。
【示例代碼】:代碼9.19實現了設定不同的區域代碼,根據不同的區域代碼瀏覽將顯示不同格式的日期。
代碼9.19?<fmt:setLocale>標簽示例:fmtdemo07.jsp
<%@ page language="java" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date"></jsp:useBean>
<html>
?<head>??
??? <title>I18N標簽庫</title>
?</head>
?<body>
?? <H4><c:out value="<fmt:setlocale>標簽的使用"></c:out></H4>
?? <hr>
?? <fmt:setLocale value="en_us" />
?? <fmt:formatDate value="${date}"?type="both" dateStyle="full" timeStyle="full"/>
?? <hr>
?? <fmt:setLocale value="zh_cn" />
?? <fmt:formatDate value="${date}"?type="both" dateStyle="full" timeStyle="full"/>
?? <hr>
?? <fmt:setLocale value="zh_TW"/>
?? <fmt:formatDate value="${date}"?type="both" dateStyle="full" timeStyle="full"/>
?? </body>
</html>
【代碼解析】:
(1)瀏覽器默認跟您使用的操作系統的語言相同,因此默認值zh_cn。使用<fmt:setLocale/>標簽設置使用的語言為en_us(英語)。使用<fmt:formateDate>格式化輸出的時間字符串,該標簽會根據不同的語言輸出不同的日期格式。
(2)使用的語言修改為zh_cn,再次用格式化輸出。
(3)使用語言修改為zh_TW,輸出格式化后的時間。
2.<fmt:requestEncoding>標簽
該標簽用于設定請求的編碼格式。功能同servletRequest.setCharacterEncoding()方法相同。
【語法】:
<fmt:requestEncoding [value=”charEncoding”]/>
【參數說明】:
value屬性用來指定使用的編碼集例如:gbk、gb2312等。當沒有給出value的值時將會自動搜索取尋找合適的編碼方式,因此能夠很好的解決中文亂碼問題。
9.4?SQL標簽庫
JSTL提供了與數據庫相關操作的標簽,可以直接從頁面上實現數據庫操作的功能,在開發小型網站是可以很方便的實現數據的讀取和操作。本章將詳細介紹這些標簽的功能和使用方法。
SQL標簽庫從功能上可以劃分為兩類:設置數據源標簽、SQL指令標簽。
引入SQL標簽庫的指令代碼為:
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
9.4.1?設置數據源
使用<sql:setDataSource>標簽可以實現對數據源的配置。
【語法1】:直接使用已經存在的數據源。
<sql:setDataSource dataSource=”dataSource”[var=”name”]
??????????????????????????? [scope=”page|request|session|application”]/>
【語法2】:使用JDBC方式建立數據庫連接。
<sql:setDataSource driver=”driverClass” url=”jdbcURL”
?????????????????????????????????????????????? user=”username”
?????????????????????????????????????????????? password=”pwd”????????????????
?????????????????????????????????????????????? [var=”name”]
?????????????????????????????????????????????? [scope=”page|request|session|application”]/>
【參數說明】:見表9-15
表9-15?<sql:DataSource>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   dataSource  |   數據源  |   是  |   String Javax.sql.DataSource  |   否  |   無  | 
|   driver  |   使用的JDBC驅動  |   是  |   String  |   否  |   無  | 
|   url  |   連接數據庫的路徑  |   是  |   String  |   否  |   無  | 
|   user  |   連接數據庫的用戶名  |   是  |   String  |   否  |   無  | 
|   password  |   連接數據庫的密碼  |   是  |   String  |   否  |   無  | 
|   var  |   指定存儲數據源的變量名  |   否  |   String  |   否  |   無  | 
|   scope  |   指定數據源存儲的JSP范圍  |   否  |   String  |   否  |   page  | 
提示:是否必須是相對的,比如說如果使用數據源則,driver、url等就不再被使用。如果使用JDBC則要用到driver、url、user、password屬性。
例如連接SQL Server需要進行如下配置:
Driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url=” jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=pubs"
user=”sa”
password=””
使用<fmt:setDataSource>配置的代碼如下:
<fmt:setDataSource driver=”com.microsoft.jdbc.sqlserver.SQLServerDriver”
?????????????????? url=”jdbc.microsoft:sqlserver://localhost:1433;DatabaseName=pubs”
?????????????????? user=”sa”
?????????????????? password=””>
如果連接其他數據庫,只須把相對應的項修改即可。
提示:可以把數據連接的配置存入session中,如果再用到數據庫連接只須配置使用DataSource屬性。
9.4.2?SQL操作標簽
JSTL提供了<sql:query>、<sql:update>、<sql:param>、<sql:dateParam>和<sql:transaction>這5個標簽,通過使用SQL語言操作數據庫,實現增加、刪除、修改等操作。下面將介紹這5個標簽的功能和使用方式。
1.<sql:query>標簽
<sql:query>標簽用來查詢數據。
【語法1】:
<sql:query sql=”sqlQuery” var=”name” [scope=”page|request|session|application”]
?????????????????? [dataSource=”dateSource”]
?????????????????? [maxRow=”maxRow”]
?????????????????? [startRow=”starRow”]/>
【語法2】:
<sql:query var=”name” [scope=”page|request|session|application”]
?????????????????? [dataSource=”dateSource”]
?????????????????? [maxRow=”maxRow”]
?????????????????? [startRow=”starRow”]
>?
sqlQuery
</sql:query>
【屬性說明】:見表9-16。
表9-16?<sql:query>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   sql  |   查詢數據的SQL語句  |   是  |   String  |   是  |   無  | 
|   dataSource  |   數據源對象  |   是  |   String Javax.sql.DataSoutce  |   否  |   無  | 
|   maxRow  |   設定最多可以暫存數據的行數  |   是  |   String  |   否  |   無  | 
|   startRow  |   設定從那一行數據開始  |   是  |   String  |   否  |   無  | 
|   var  |   指定存儲查詢結果的變量名  |   否  |   String  |   是  |   無  | 
|   scope  |   指定結果的作用域  |   否  |   String  |   否  |   page  | 
使用<sql:query>必須指定數據源,dataSource是可選的,如果未給定該屬性標簽會在page范圍內查找是否設置過數據源,如果沒有找到將拋出異常。
一般情況下使用<sql:setDateSource>標簽設置一個數據源存儲在session范圍中,當需要數據庫連接時使用dataSource屬性并實現數據庫的操作。
<sql:query>的var屬性是必須的用來存放結果集,如果沒有指定scope范圍則默認為page,即在當前頁面我們可以隨時輸出查詢結果。結果集有一系列的屬性如表9-17所示。
maxRows和startRow屬性用來操作結果集,使用SQL語句首先吧數據放入內存中,檢查是否設置了startRow屬性,如果設置了就從starRow指定的那一行開始取maxRows個值,如果沒有設定則從第一行開始取。
表9-17?結果集參數說明
|   屬性名  |   類型  |   說明  | 
|   rowCount  |   int  |   結果集中的記錄總數  | 
|   Rows  |   Java.util.Map  |   以字段為索引查詢的結果  | 
|   rowsByIndex  |   Object[]  |   以數字為作索引的查詢結果  | 
|   columnNames  |   String[]  |   字段名稱數組  | 
|   limitedByMaxRows  |   boolean  |   是否設置了maxRows屬性來限制查詢記錄的數量  | 
提示:limitedByMaxRows用來判斷程序是否收到maxRows屬性的限制。并不是說設定了maxRows屬性,得到結果集的limitedByMaxRows的屬性都為true,當取出的結果集小于maxRows時,則maxRows沒有對結果集起到作用此時也為false。例如可以使用startRow屬性限制結果集的數據量。
結果集的作用就是定義了數據在頁面中的顯示方式。下面給出了結果集每個屬性的作用。
q????????rowCount屬性。該屬性統計結果集中有效記錄的量,可以使用于大批量數據分頁顯示。
q????????Rows屬性。等到每個字段對應的值。返回的結果為:字段名={字段值···}
q????????rowsByIndex屬性。常用得到數據庫中數據的方式,從有效行的第一個元素開始遍歷,到最后一個有效行的最后一個元素。
q????????columnNames屬性。用于得到數據庫中的字段名。
q????????limitedByMaxRows屬性。用于判斷是否受到了maxRows的限制。
【示例代碼】:代碼9.20給出了配置數據庫連接,和使用<sql:query>查詢數據以及結果集屬性的使用。
代碼9.20?數據庫示查詢示例:sqldemo01.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ page contentType="text/html;charset=GBK"%>
<html>
<head>
?<title>JSTL: SQL標簽</title>
</head>
<body >
<h3>SQL標簽庫</h3>
<hr>
<sql:setDataSource driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"
???????? url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs"
???????? user="sa" password="" />
<sql:query var="result" sql="select * from person" maxRows="2" startRow="1"/>
結果集的實質是:${result}<br>
得到的行數為:${result.rowCount}<br>
是否收到了maxRows的限制:${result.limitedByMaxRows}
<hr>
<table border="1" align="center">
<tr><c:forEach var="columnName" items="${result.columnNames}">
<td>
<c:out value="${columnName}"/>
</td>
</c:forEach> </tr>
<c:forEach var="row" items="${result.rowsByIndex}">
<tr>
<c:forEach var="column" items="${row}">
<td><c:out value="${column}"/></td>
</c:forEach>
</tr>
</c:forEach>
</table>
</body>
</html>
【代碼解析】:
(1)配置數據源。使用<sql:dataSource>標簽配置數據源,因為只共本頁使用因此存儲在默認的page范圍中。
(2)使用<sql:query>標簽進行數據庫查詢,并定義了maxRows和startRow屬性。并把結果集存儲于作用于page范圍的result變量。使用${result}輸出可以發現結果集就是一個ResultImpl類。
提示:在進行數據源配置時程序不會檢查數據庫連接是否配置正確,直接根據設定的數據庫及連接訪問,如果沒有找到則拋出操作的表異常,因此要放如<c:catch></c:catch>同時在編寫程序時一定要注意數據源是否配置正確。
(3)使用結果集的rowCount屬性得到記錄的總量。代碼為:
${result.rowCount}
(4)使用結果集的limitedMaxRows屬性判斷是否收到maxRows設定的影響。代碼為:
${result.limitedMaxRows}
(5)從結果集中得到數據庫中定義的所有的字段。${result.columnnames}得到的結果是一個字符串數組,因此需要使用<c:forEach>循環輸出。代碼如下:
<c:forEach var="columnName" items="${result.columnNames}">
<c:out value="${columnName}"/>
</c:forEach>
(6)從結果集中得到所有的值。首先要遍歷每一行,然后遍歷每一行中的元素,因此需要循環嵌套。代碼如下:
<c:forEach var="columnName" items="${result.columnNames}">
<c:out value="${columnName}"/>
</c:forEach>
<c:forEach var="row" items="${result.rowsByIndex}">
<c:forEach var="column" items="${row}">
<c:out value="${column}"/></td>
</c:forEach>
</c:forEach>
提示:在代碼解析中省略了html元素表格等標簽的元素,本示例適用于任何數據庫表,只要把數據庫的URL、使用的JDBC進行相應的配置和操作的數據表名進行相應的修改即可看到結果。
2.<sql:update>標簽
<sql:update>用來實現操作數據庫如:使用create、update、delete和insert等SQL語句,并返回影響記錄的條數。
【語法1】:SQL語句放在標簽屬性中。
<sql:update sql=”SQL語句” [var=”name”] [scope=”page|request|session|application”]
??????????????????????????????????????????????????????? [dateSource=”dateSource”]/>
【語法2】:SQL語句放在標簽體內。
<sql:update [var=”name”] [scope=”page|request|session|application”]
??????????????????????????????????????????????????????? [dateSource=”dateSource”]
>?
SQL語句
</sql:update>
【參數說明】:見表9-18。
表9-18?<sql:update>標簽屬性說明
|   參數名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   sql  |   查詢數據的SQL語句  |   是  |   String  |   是  |   無  | 
|   dataSource  |   數據源對象  |   是  |   String Javax.sql.DataSoutce  |   否  |   無  | 
|   var  |   指定存儲查詢結果的變量名  |   否  |   String  |   是  |   無  | 
|   scope  |   指定結果的作用域  |   否  |   String  |   否  |   page  | 
提示:<sql:update>標簽的屬性同<sql:query>標簽的屬性相比只減少了maxRows和startRow2個屬性。其他參數用法一樣。
使用<sql:update>可以實現數據表的創建、插入數據、更行數據、刪除數據。使用時只須在標簽中放入正確的SQL語句即可,同時要捕獲可能產生的異常。本節只對一個簡單的插入操作進行說明。
【示例代碼】:代碼9.21實現了創建一個表、實現數據的插入。
代碼9.21?數據庫創建、數據插入示例:sqldemo02.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ page contentType="text/html;charset=GBK"%>
<html>
<head>
?<title>JSTL: SQL標簽</title>
</head>
<body >
<h3>SQL標簽庫</h3>
<hr>
<sql:setDataSource driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"
???????? url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs"
???????? user="sa" password="" />
實現數據庫表的創建<br>
<sql:update var="result1">
create table c_user (
???????? ?id int primary key ,
???? name varchar(80),
???? sex varchar(80),
)
</sql:update>
<c:catch var="error">
<sql:update var="result2" >
insert c_user values(05,'Linda','女')
insert c_user values(01,'Rom','男' )
</sql:update>
影響的記錄數為:<c:out value="${result2}"></c:out>
</c:catch>
<c:out value="${error}"></c:out><br>
<hr>
</body>
</html>
【代碼解析】:
(1)配置數據源。
(2)使用<sql:update>標簽創建一個新表。
(3)向表中插入兩行數據。
提示:本示例也沒有針對固定的表進行操作,在使用時直接運行即可,如果使用的是其他數據庫,需要更改數據源配置和SQL語句部分修改。
圖9.25?SQL表的內容
3.<sql:param>標簽
<sql:param>標簽用于動態的為SQL語句設定參數,同<sql:query>標簽共同使用。可以防止SQL注入作用類似于java.sql.PreparedStatement。
【語法1】:
<sql:param value=”value”/>
【語法2】:
<sql:param>
Value
</sql:param>
【參數說明】:
value的作用為SQL中的參數賦值。
【使用示例】:
<sql:query var=”result”>
select * from person where?序號=?
<sql:query>
4.<sql:dateParam>標簽
<sql:dataParam>標簽主要用于為SQL標簽填充日期類型的參數值。
【語法】:
<sql:dateParam value=”date”[type=”timestamp|time|date”]/>
【參數說明】:
q????????value屬性:java.util.Date類型的參數。
q????????type屬性:指定填充日期的類型timestamp(全部日期和時間)、time(填充的參數為時間)、date(填充的參數為日期)。
5.<sql:transaction>標簽
<sql:transaction>標簽提供了數據操作的一種安全機制(即事務回滾),當操作數據庫的某條SQL語句發生異常時,取消<sql:transaction>標簽體中的所有操作,恢復原來的狀態,重新對數據庫進行操作。
【語法】:
<sql:transaction [dataSource=”dataSource”]
[isolation=”read_committed|read_uncommitted|repeatable|serializable”]
>?
<sql:query>
<sql:uptade>
</sql:transation>
9.5?XML標簽庫
JSTL提供了操作xml文件的標簽庫,使用xml標簽庫可以省去使用Dom和SAX標簽庫的繁瑣,能輕松的讀取xml文件的內容。
9.5.1?XML核心標簽庫
1.<x:parse>標簽
<x:parse/>標簽用來解析指定的xml文件。
【語法1】:
<x:parse?doc=”xmlDocument”
{var=”name”[scope=”page|request|session|application”]|varDom=”name”[scope=”page|request|session|application”]}
systemId=”systemId”
filter=”filter”
/>
【語法2】:
<x:parse
{var=”name”[scope=”page|request|session|application”]|varDom=”name”[scope=”page|request|session|application”]}
systemId=”systemId”
filter=”filter”
>?
xmlDocument
</x:parse>
【參數說明】:見表9-20。
表9-20?<x:parse>標簽屬性說明
|   屬性名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   doc  |   指定解析的xml文件  |   是  |   String/Reader  |   是  |   無  | 
|   var  |   存儲解析后的xml文件  |   否  |   String  |   否  |   無  | 
|   scope  |   指定var的JSP范圍  |   否  |   String  |   否  |   page  | 
|   varDom  |   以(org.w3c.dom.Doucemet)的形式存儲解析的xml文件  |   否  |   String  |   否  |   無  | 
|   scopeDom  |   指定varDom的JSP范圍  |   否  |   String  |   否  |   page  | 
|   systemId  |   xml文件的url  |   是  |   String  |   否  |   無  | 
|   filter  |   解析xml文件的過濾器  |   否  |   Org.xml.sax.Filter  |   否  |   無  | 
提示:doc指定解析的xml文件并不是指定xml文件的路徑,而是同<c:import>共同使用,由<c:import>加載并存儲,然后使用<x:parse>解析。
例如:如果解析person.xml文件需要通過如下代碼實現對xml文件的解析。
<c:import var="docString" url="person.xml"/><!--引入person.xml文件-->
<x:parse var="doc" doc="${docString}"/>
<c:import>語句用來導入或存儲文件到JSP。如果不使用var來存儲,xml文件將顯式的出現在JSP文件中。
<x:parse>標簽只用來解析xml文件,并不顯示xml文件中的內容,如果想得到xml的節點元素或值需要使用<x:out>元素來實現。
2.<x:out>標簽
<x:out>標簽主要用來輸出xml的信息。
【語法】:
<x:out select=”XpathExperssion”[excapeXml=”true|false”]>
【參數說明】:見表9-21。
表9-21?<x:out>標簽屬性說明
|   屬性名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   select  |   指定使用的XPath語句  |   否  |   String  |   是  |   無  | 
|   escapeXml  |   是否轉換特殊字符。如<等  |   否  |   boolean  |   是  |   true  | 
提示:使用XPath語句需要用到xalan.jar支持包,可以從示例程序的lib中獲取,獲得直接從myEclipse中可以找到。
【示例代碼】:
3.<x:set>標簽
<x:set>標簽用于將從xml文件節點解析的內容存儲到JSP屬性范圍中。
【語法】:
<x:set select=”XPathExperssion” var=”name” scope=”page|request|session|application”>
【參數說明】:
(1)select通過指定的XPath表達式語句獲取節點的值。
(2)var指定用于存儲值的變量名。
(3)指定var的JSP屬性范圍。
9.5.2?XML流程控制
使用xml標簽庫的流程控制標簽可以迭代處理xml文件的內容,流程控制可以分為以下兩個方面的內容:
(1)條件判斷。
(2)循環功能。
1.<x:if>
<x:if>主要用于條件判斷。
【語法1】:未含有本體內容。
<x:if select=”XPathExperssion” var=”name”[scope=”page|request|session|application”]/>
【語法2】:含有本體內容。
<x:if select=”XPathExperssion” var=”name”[scope=”page|request|session|application”]
>?
本體內容
</x:if>
語法1只把根據條件表達式得到的結果的存儲在JSP范圍中,語法2根據<x:if>標簽根據條件表達式的結果決定是否執行本體內的代碼。
【參數說明】:
(1)select用來指定使用的XpathExperssion表達式。
(2)var設定標量名用來存儲表達式的結果。
(3)scope指定var存儲的JSP屬性范圍。
2.<x:choose>、<x:when>和<x:otherwise>標簽
同核心標簽庫的<c:choose>、<c:when>和<c:otherwise>標簽作用相似,只是使用的條件表達式不同。
<x;choose>是主標簽,<x:when>和<x:otherwise>放在<x:choose>標簽體內共同使用。
【語法】:
<x:choose>
<x:when>
<x:when>
<x:otherwise>
</x:choose>
其中只有<x:when>有屬性。
【語法】:
<x:when select=”XPathExperssion”>
3.<x:forEach>標簽
<x;forEach>標簽實現了對xml文檔的遍歷。
【語法】:
<x:forEach select=”XPathExperssion”[var=”name”][varStartus=”StartusName”]
[begin=”begin”][end=”end”][step=”step”]
>?
//標簽主體
</x:forEach>
【參數說明】:見表9-22。
表9-22?<x:forEach>標簽屬性說明
|   屬性名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   select  |   指定使用的XPath語句  |   否  |   String  |   是  |   無  | 
|   var  |   用于存儲表達式的結果  |   否  |   String  |   否  |   無  | 
|   varStatus  |   用來存放循環到的變量的相關信息  |   否  |   String  |   否  |   無  | 
|   begin  |   循環的起始位置  |   是  |   int  |   否  |   無  | 
|   end  |   循環的終止位置  |   是  |   int  |   否  |   無  | 
9.5.3?xml的文件轉換
<x:transform>和<x:param>能輕易使用XSLT樣式包裝xml文件,成為另一種顯示方式。
1.<x:transform>標簽
使用該標簽可以輕松的實現xml到XSLT的轉化。
【語法1】:
<x:transform doc=”xmldoc” xslt=”XSLTStytlesheet”[docSystemId=”xmlsystemid”]
[result=”result”]
[var=”name”]
[scope=”scopeName”]
[xsltSystemId=”xsltsystemid”]/>
【語法2】:
<x:transform doc=”xmldoc” xslt=”XSLTStytlesheet”[docSystemId=”xmlsystemid”]
[result=”result”]
[var=”name”]
[scope=”scopeName”]
[xsltSystemId=”xsltsystemid”]
>?
<x:param/>
</x:transform>
【語法3】:
<x:transform doc=”xmldoc” xslt=”XSLTStytlesheet”[docSystemId=”xmlsystemid”]
[result=”result”]
[var=”name”]
[scope=”scopeName”]
[xsltSystemId=”xsltsystemid”]
>?
Xml文件內容
<x:param/>
</x:transform>
【參數說明】:見表9-23。
表9-23?<x:transform>標簽屬性說明
|   屬性名  |   說明  |   EL  |   類型  |   必須  |   默認值  | 
|   doc  |   指定xml文件來源  |   是  |   String  |   是  |   無  | 
|   xslt  |   轉化xml的樣式模板  |   是  |   String  |   是  |   無  | 
|   docSystemId  |   xml文件的URI  |   是  |   String  |   否  |   無  | 
|   xsltSystemId  |   xslt文件的URI  |   是  |   String  |   否  |   無  | 
|   result  |   用來存儲轉換后的結果對象  |   是  |   java.xml.transform  |   是  |   無  | 
|   var  |   以org.w3c.dom.Documet類型存儲轉換后的結果  |   否  |   String  |   否  |   無  | 
|   scope  |   var的屬性范圍  |   否  |   String  |   否  |   無  | 
2.<x:param>標簽
該標簽用來為<x:transform>標簽轉換參數。
【語法1】:
<x:param name=”name” value=”value”/>
【語法2】:
<x:param name=”name” value=”value”
>?
Value
</x:param>
【參數說明】:
(1)name指定參數的名稱。
(2)value指定參數值。
轉載于:https://www.cnblogs.com/houqijun/p/4673133.html
總結
                            
                        - 上一篇: 求一个qq网名女生黑白。
 - 下一篇: 高数: lim(x→∞)(sinx