經過上一篇對於Tag標籤的介紹之後,大家對於tag應該有點感覺吧。我們今天就會來介紹JSTL裡面的Core類型的標籤。
前言
經過上一篇對於Tag標籤的介紹之後,大家對於tag應該有點感覺吧。我們今天就會來介紹JSTL裡面的Core類型的標籤。
Core tag的概括介紹
JSTL裡面有6大類的tag,而core tag屬於專門處理邏輯判斷和iteration的tag。
要使用,首先要在jsp頁面裡面加上taglib directive element,把uri指向:http://java.sun.com/jsp/jstl/core。而prefix通常來說core都是指定成為c。當然如果要改prefix可以自己改成喜歡的,只要記得在呼叫的時候要和prefix對應。因此,taglib directive element的設定如下:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
接下來我們會一一介紹core tag裡面有提供的功能。
c:out 標籤
<c:out>標籤主要作用是把EL裡面的內容輸出來(到out裡面,因此會出現在畫面)。
c:out總共有3個attribute:
- value - 要輸出的內容。這邊使用EL表示要輸出什麼
- default - 假設在value裡面輸入的EL沒有值的時候,顯示的預設值
- escapeXml - 是否要把輸出的特殊標籤,例如<encode過。
範例:
<c:out value="${param.out }" default="out missing" />
上面表示如果query string有帶上out,就輸出out的內容,如果沒有,則輸出「out missing」。
這邊或許大家會覺得我可以直接透過EL輸出就好了,為什麼要用out?原因很簡單:
- 如果輸出的內容是數字或者日期,out會依照設定的locale去顯示(例如日期年月日輸出的排序),而EL不會。
- out有提供預設值,用EL需要多判斷
邏輯判斷類型
core tag裡面有兩個邏輯判斷的tag分別是if和choose。if是用來判斷只有符合條件才顯示,但是他不能達到像程式裡面的if else的動作。而choose專門做if else 類型的邏輯判斷。
如果有寫過xsl,那麼這兩個邏輯判斷和xsl很像。
c:if
基本上有一個test的attribute。只有返回true會執行包在c:if裡面的內容。
test裡面可以直接比對字串(不分大寫),或者返回boolean的參數。test裡面也可以使用EL。
範例:
<c:if test="${param.action == 'add'}">
<form>
name:<input type="text" name="name" />
<br />
age:name:<input type="text" name="age" />
</form>
</c:if>
c:choose、c:when、c:otherwise
基本上c:choose包著c:when和c:otherwise。c:choose其實很像程式裡面的switch。c:when就是每一個case而c:otherwise就是default。
不過和switch不同的是,c:when 之間的test判斷不需要一樣的。不過和switch一樣的是,c:choose裡面只會有一個符合內容的東西會出現。
範例:
<c:when test="${param.out == 'out' }">
<p>out value </p>
</c:when>
<c:when test="${param.out == 'hello' }">
hello value
</c:when>
<c:otherwise>
no out
</c:otherwise>
</c:choose>
c:forEach 用來iterate集合
c:forEach其實就是程式裡面的for、while、foreach的使用。
達到for的效果
在c:forEach有4個attribute:
- var - 參數用來儲存目前迴圈用來判斷的值
- begin - var參數的初始值
- end - 當var等於小於end的時候會停下來
- step - 每一個迴圈結束要對var參數增加step的值。
<c:forEach var="i" begin="0" end="100" step="1">
<span>${ i }</span>
</c:forEach>
<%
for(int i=0; i <= 100; i++)
{
%>
<span><%=i %></span>
<%
}
%>
上面有用c:forEach和Scriptlet for來達到一樣效果做比對。
達到foreach的效果
c:forEach有兩個attribute:
- var - iterate的時候每一筆的名稱代表
- items - 集合的名稱
範例:
<%
List<Person> persons = new ArrayList();
Person person1 = new Person();
person1.setAge(10);
person1.setName("a");
Person person2 = new Person();
person2.setAge(20);
person2.setName("b");
persons.add(person1);
persons.add(person2);
request.setAttribute("persons", persons);
%>
<c:forEach var="person" items="${ persons }">
<div>
<p>name: ${person.name }</p>
<p>age: ${person.age }</p>
</div>
</c:forEach>
<br />
<%for(Person person: persons)
{
%>
<div>
<p>name:<%= person.getName()%></p>
<p>age:<%= person.getAge()%></p>
</div>
<%
}
%>
和之前一樣,也是用了JSTL的方式和scriptlet來做比對。
c:forEach的Attribute - varStatus
相信剛剛上面如果在iterate集合的時候,對於沒有辦法知道此物件在目前集合裡面的index是多少,或者是否是最後一個物件等問題,c:forEach有一個attribute 叫做varStatus可以設定名稱。在c:forEach裡面就可以使用設定的名稱來取得一些資訊。
varStatus屬於: javax.servlet.jsp.jstl.core.LoopTagStatus 因此他有的值例如isFirst(),就可以被我們透過EL來取得(${{varStatus name}.First}。
c:forTokens - 對字串透過分隔符號做iterate
c:forTokens和c:forEach基本一樣,都有一樣的Attribute,差別在於它的items attribute接受的是string然後給予delims(分割符號)。
<c:forTokens var="alpha" items="a,b,c,d,e,f" delims=",">
<span>${ alpha }</span>
</c:forTokens>
c:set - 修改或創建數值
c:set基本的作用就是創建或者修改數值。他總共有5個Attribute:
- value - 要創建或者修改的值
- scope - 表示這個參數的scope位置。記得總共4個:page、request、session、context
- var - 是要寫入的名稱(換句話說如果要取出來使用此名稱)。不能使用EL。如果不存在會創建,如果存在就修改。 不能和target同時存在,同時只能設定primitive的type
- target - 這個不能和var同時存在。target要使用EL指定,而且可以處理java bean或者map。target指定的一定要存在要不然會exception。
- property - 給target是java bean的時候設定要修改哪一個property。而這個property一定要有setter要不然會有exception
var attribute - 處理primitive type
基本上var不能使用EL,只能是字串。其實和scriptlet裡面的xxx.setAttribute({var}, {value})一樣概念。xxx是4個scope。
如果var有存在就會變成更新,如果不存在就會創建。
value是會要設定的值,不過也可用<c:set var="a">{value}</c:set>。
target attribute - 處理java bean和map
target不能和var在同一個c:set裡面出現。而target的設定一定使用EL指定java bean或者map的名稱。需要記得,這邊指定target一定要已經被創建過了。要不然會有 exception。
property在target是java bean的時候指的是那個java bean裡面的setXXX。一定要有存在這個set,如果沒有會有exception。而如果target是map的情況下, property代表的是key。如果這個key還不存在會被創建,如果有存在就更新。
c:remove - 刪除某一個參數
此只有兩個Attribute,一個是var和scope。
var只能輸入字串,不能是EL。
c:catch - 接住Exception
c:catch只有一個attribute是var,而他包住的就是如果有exception出來就會存到var裡面,然後就可以在別的地方把它取出來。
<c:catch var="e">
<c:import url="http://www.google.com" />
</c:catch>
<div>
exception: ${ e.message}
</div>
當沒有網路的時候,如果沒有c:catch會造成整個出錯。
c:import - 取得別頁面的內容
和我們jsp include action 概念一樣,不過更厲害的是它可以包括外部網站內容直接embed到網站。
總共有6個Attribute:
- url - 要取得那個位置的內容 - 如果給的是http開頭就外部鏈接,而以/開頭則是內部。
- var - 如果有設定,則會把取回來的內容存在這個var的參數里面
- varReader - 不能和var同時存在。和var差別在於,var儲存是string type。如果是varReader就是用Reader來儲存,可以讓其他在做處理。
- scope - 參數的scope
- context - 如果有設定,url一定是內部位置。因此有設定,context和url都是/開始。而context設定的就是url的相對路徑的起始位置。
例如:
<c:import url="/HelloWorld.jsp" />
c:url
這個可以提供url rewrite的機制(基本上就是把SessionId放到query String裡面,來達到當cookie被使用者disable的時候還是能夠使用session)。
c:redirect
類似於redirect的效果。也是有url和context attribute。基本和c:import裡面設定一樣。
c:param
主要作為有url標籤的子標籤,代表著要傳過去的query string。
例如:
<c:import url="/HelloWorld.jsp">
<c:param name="a" value="11112222" />
<c:param name="b" value="sdafsadf" />
</c:import>
結語
這一篇介紹都是JSTL裡面的core tag帶來的的功能,而core的功能基本上都是在做控制和數據的取得和修改。
希望大家透過這一篇的介紹就可以開始使用JSTL來代替Scriptlet。