什么是JSTL
JSTL全稱為 JSP Standard Tag Library 即JSP標準標簽庫。
JSTL作為最基本的標簽庫,提供了一系列的JSP標簽,實現了基本的功能:集合的遍歷、數據的輸出、字符串的處理、數據的格式化等等!
為什么要使用JSTL
- EL表達式不夠完美,需要JSTL的支持!在JSP中,我們前面已經用到了EL表達式,體會到了EL表達式的強大功能:使用EL表達式可以很方便地引用一些JavaBean以及其屬性,不會拋出NullPointerException之類的錯誤!但是,EL表達式非常有限,它不能遍歷集合,做邏輯的控制。這時,就需要JSTL的支持了!
- Scriptlet的可讀性,維護性,重用性都十分差!JSTL與HTML代碼十分類似,遵循著XML標簽語法,使用JSTL讓JSP頁面顯得整潔,可讀性非常好,重用性非常高,可以完成復雜的功能!
- 在JSP中不推薦使用scriptlet輸出,推薦使用JSP標簽。
使用JSTL標簽庫步驟:
- 導入jstl.jar和standard.jar開發包
- 在JSP頁面中用tablib指令引入需要用到的JSTL標簽
core標簽庫
- core標簽庫是JSTL的核心標簽庫,實現了最基本的功能:流程控制、迭代輸出等操作!
- core標簽庫的前綴一般是c
c:out
- 簡單使用一下
<%
session.setAttribute("name", "zhongfucheng");
%>
//<c:out/>標簽支持標簽體,default屬性上的數據可以寫在標簽體中
//<c:out value="${name}" escapeXml="true">您要的數據找不著</c:out>
<c:out value="${name}" default="您要的數據找不著" escapeXml="true"/>
- 我們發現上面的代碼實現的效果和EL表達式是一樣的,它出色的地方就多了兩個屬性,default和escapeXml屬性。如果我們用到這兩個屬性,我們就使用該標簽,如果沒有用到這兩個屬性就用EL表達式就可以了。
c:set
- 該標簽有5個屬性,用起來有稍微有些復雜了!現在要記住的就是:var屬性操作的是Integer、Double、Float、String等類型的數據,target屬性操作的是JavaBean或Map對象的數據,scope代表的是Web域,value是值,property是對象的屬性!
使用var屬性
既然var屬性只能操作Integer、Double、String等類型,那么存在var屬性就一定沒有property屬性(property代表的是對象的成員屬性,Integer、String這些類型哪來的成員變量呀)
下面的代碼流程是這樣的:創建了一個name的變量,設置的值為zhongfucheng,范圍是page
<c:set var="name" value="fucheng" scope="page"/>
${name}
- 效果:
- 當然了,set標簽也支持標簽體,value的值可以寫在標簽體里邊
<c:set var="name" scope="page">
zhongfucheng
</c:set>
- 使用var屬性和scope屬性實現計數器
<%--由于下面變量需要做加法運算,所以要定義出來,不然服務器是不知道我的變量是Integer類型的--%>
<%
Integer sessionCount = 0;
Integer applicationCount = 0;
%>
<c:set var="sessionCount" value="${sessionCount+1}" scope="session"/>
<c:set var="applicationCount" value="${applicationCount+1}" scope="application"/>
- 效果:
使用target屬性
- 使用target屬性與之配對的是property屬性,target屬性只能操作JavaBean或Map對象,property就是對應的成員變量或key了。。
- 既然target屬性操作的是JavaBean或Map對象,那么一定是通過EL表達式來獲取到對象了。taget屬性如果獲取不到數據會拋出異常!使用target屬性就一定沒有scope屬性(scope屬性代表的是保存范圍,target的值都是獲取來的,難道你還能改變人家的范圍?)
<%--創建出JavaBean對象,設置為session范圍的屬性--%>
<jsp:useBean id="person" class="domain.Person" scope="session"/>
<%--獲取到person對象,設置age屬性的值為32--%>
<c:set target="${person}" property="age" value="32"/>
${person.age}
- 效果:
c:remove
remove標簽就相當簡單了,只有var和scope屬性,代表的是刪除域范圍的屬性
- 下面簡單來測試一下吧:
<%--創建出JavaBean對象,設置為session范圍的屬性--%>
<jsp:useBean id="person" class="domain.Person" scope="session"/>
<%--獲取到person對象,設置age屬性的值為32--%>
<c:set target="${person}" property="age" value="32"/>
${person.age}
<br>
<%--刪除session屬性--%>
<c:remove var="person" scope="session"></c:remove>
${person.age==null?"存在session的person對象被刪除了!":"我還在呢!"}
- 效果:
c:catch
該標簽主要用來處理程序中產生的異常。
catch標簽也十分簡單,只有一個var屬性,var屬性封裝了異常的信息!
<%--創建出JavaBean對象,設置為session范圍的屬性--%>
<jsp:useBean id="person" class="domain.Person" scope="session"/>
<c:catch var="message">
<%--target屬性只能是EL表達式,現在我是字符串,獲取不到對象,肯定會拋出異常的!--%>
<c:set target="person" property="age" value="32"/>
</c:catch>
${message}
- 效果:
c:if
JSTL提供了if標簽完成分支語句的實現,test屬性是不可或缺的。
var和scope屬性我看來好像沒什么用的(保存執行結果有什么用?)
- 根據傳遞過來的參數的不同顯示不同的頁面!
<%--如果帶過來的名字是zhongfucheng,那么可以登陸--%>
<c:if test="${param.name=='zhongfucheng'}">
用戶名:<input type="text" name="username"><br>
密碼:<input type="password" name="password"><br>
<input type="submit" value="登陸">
</c:if>
<%--如果帶過來的名字是ouzicheng,那么就是注冊--%>
<c:if test="${param.name=='ouzicheng'}">
用戶名:<input type="text" name="username"><br>
密碼:<input type="password" name="password"><br>
<input type="submit" value="注冊">
</c:if>
- 注意地址欄的參數!
c:choose
if標簽沒有else的功能,如果需要類似于java中的if else流程就需要使用choose標簽。
choose標簽需要聯合when和otherwise標簽一起使用!
<c:choose>
<c:when test="${param.name=='zhongfucheng'}">
你好啊,zhongfucheng
</c:when>
<c:when test="${param.name=='ouzicheng'}">
你好啊,ouzicheng
</c:when>
<c:otherwise>
你是誰啊?別隨便過來!
</c:otherwise>
</c:choose>
- 效果:
c:forEach
forEach為循環標簽,相當于Java中的while和for
之前我們在使用EL表達式獲取到集合的數據,遍歷集合都是用scriptlet代碼循環,現在我們學了forEach標簽就可以舍棄scriptlet代碼了。
向Session中設置屬性,屬性的類型是List集合
<%
List list = new ArrayList<>();
list.add("zhongfucheng");
list.add("ouzicheng");
list.add("xiaoming");
session.setAttribute("list", list);
%>
- 遍歷session屬性中的List集合,items:即將要迭代的集合。var:當前迭代到的元素
<c:forEach var="list" items="${list}" >
${list}<br>
</c:forEach>
- 效果:
- 遍歷Map對象有稍微地不一樣,我們來看一下,var屬性保存的不是每個迭代的對象,而是Map.Entry。
<%
Map map = new HashMap();
map.put("1", "zhongfucheng");
map.put("2", "xiaohong");
map.put("3", "xiaoming");
session.setAttribute("map",map);
%>
<c:forEach var="me" items="${map}" >
${me.key} ${me.value}<br>
</c:forEach>
begin默認從0開始、end默認為集合的最后一個元素、step默認為1
-
varStatus代表著當前對象被迭代的信息,它有以下的屬性。
- index【返回當前是第幾個對象,從0開始計數】
- count【已經遍歷多少個對象了,從1開始計數】
- first【是否是第一個】
- last【是否是最后一個】
- current【當前被迭代的對象】
- begin【開始的位置】
- end【最后的位置】
- step【步長】
<c:forEach var="list" items="${list}" varStatus="varStatus" >
${list}您的下標是:${varStatus.index}<br>
</c:forEach>
- 效果:
c:forTokens
該標簽類似于String類的split()和for循環的一種集合
它與forEach標簽非常相似,都有begin、end、step、items、var、varStatus屬性,不同的是forTokens標簽的items屬性里面是字符串,這個字符串會被delims屬性的內容分割成多個字符串!
<c:forTokens items="zhongfucheng,ouzicheng,xiaoming,xiaohong" var="name" delims="," >
${name}
</c:forTokens>
- 效果圖:
c:import
import標簽類似于JSP行為<jsp:include/>
和JSP指令<%include>
import標簽的屬性:
- url【指定要包含的路徑,Internet所有的url都可以】
- context【訪問同一個web容器的其他資源,以"/"開頭】
- var【保存導入的文件的內容,以String類型存儲】
- socpe【保存的范圍,默認是page】
- charEncoding【字符編碼】
- varReader【保存導入文件的內容,以Reader類型存儲】
當然了,import標簽功能更加更大!強大在哪里呢?import標簽可以引入Internet網頁上的內容,也就是說,csdn也可以引入進來!
- 我們來用一下把!
<c:import url="http://www.csdn.net" charEncoding="UTF-8" />
- 我們一看,是沒有樣式的:
- 打印csdn的源代碼:
<c:import url="http://www.csdn.net" charEncoding="UTF-8" var="net"/>
CSDN的源碼是:<br><br><br><br><br>
<c:out value="${net}" escapeXml="true"></c:out>
- 效果:
c:param
- 在JSP頁面進行URL的相關操作時,經常要在URL地址后面附加一些參數。
c:url
url標簽十分實用!在瀏覽器禁用Cookie的時候,我們之前學Servlet時解決辦法是:response.encodeURL()。url標簽也可以實現這樣的功能,再配合param標簽使用,就十分實用了!
- 我們配合param標簽來使用一下吧!
<c:url value="2.jsp" var="url">
<c:param name="name" value="中國!">
</c:param>
</c:url>
<a href="${url}">我經過了URL地址重寫!</a>
- 效果:
c:redirect
redirect標簽用于實現Redirect功能,當然了,此標簽也能夠配合param標簽使用!
- 簡單使用一下,重定向到2.jsp,帶了一個參數:
<c:redirect url="2.jsp" >
<c:param name="name" value="zhongfucheng">
</c:param>
</c:redirect>
- 在2.jsp中獲取到參數
fmt標簽庫
fmt標簽庫也叫做國際化標簽庫。這里就不詳細說明了,等我講到Web 國際化的時候才講吧!
fn方法庫
fn方法庫也叫做EL函數庫、fn標簽庫。這個在講解EL表達式的時候有詳細的說明,可轉移到我EL表達式的博文中!
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章的同學,可以關注微信公眾號:Java3y