JSP标簽、EL表達式、JSTL
(一)JSP标簽技術
一、JSP标簽技術概述
- jsp本質上是一種動态web資源開發技術 , 看起來像是html , 但其中可以寫java代碼 , 非常友善用來開發動态web資源 。
- 但是一旦在jsp中寫了太多的java代碼 , 仍然會造成代碼和标簽混雜在一起 , 不便于開發維護 , 是以sun公司在JSP2.0開始已經不再推薦 在jsp頁面中出現任何一行java代碼了 。
- 所有的java代碼應該替換問為jsp标簽技術來實作 。
- jsp标簽技術提供的标簽 , 看起來像是一個标簽 , 但本質上仍然是Java代碼 , 是以仍然是web動态資源開發技術
- 由于JSP原生的标簽庫标簽比較少, 且不太好用 , 是以目前的開發越來越趨勢:
- jsp原生标簽 隻替代jsp頁面中的轉發和包含的java代碼
- el表達式替代jsp頁面中腳本表達式
- JSTL替代jsp頁面中的腳本片段 。
(二)JSP标簽
一、jsp标簽
- 是sun公司 在jsp2.0中提供的原生的标簽 不需要導入任何開發包就可以直接使用
- 但是 這個标簽庫中的标簽 比較少 且不太好用 是以現在用的很少
- 我們隻需了解幾個即可
<jsp:inclue> 用來替代request.getRequestDispatcher().include()實作頁面包含 <jsp:forward>用來替代request.getRequestDispatcher().forward() <jsp:param>配合前兩個标簽使用,可以在包含或轉發時,帶一些參數過去
(三)EL表達式
一、概述及注意
- 全稱叫做Expression Language ,用來替代jsp頁面中的jsp的腳本表達式 <%= java表達式%>
- el表達式的形式 $(el表達式)
- 注意:
- el隻能擷取域中的資料
- el隻能擷取不能周遊
- el隻能擷取不能修改
二、擷取資料
- 擷取常量資料
- 支援包括數值類型 、 在字元串類型 、 布爾類型
<%--擷取常量資料 --%> ${123.342 } ${"abc" } ${true } ${false }
- 支援包括數值類型 、 在字元串類型 、 布爾類型
- 擷取變量中的資料
- el中直接寫變量的名稱, el會按照由小到大的順序自動搜尋四大作用域找該名稱對應的值 , 如果找到則傳回 ,找不到則傳回空字元串 。
<%--擷取變量 --%> <% //pageContext.setAttribute("country", "CN"); //request.setAttribute("country", "US"); //session.setAttribute("country", "UK"); //application.setAttribute("country", "JP"); %> <%= pageContext.findAttribute("country") %> ${country }
- el中直接寫變量的名稱, el會按照由小到大的順序自動搜尋四大作用域找該名稱對應的值 , 如果找到則傳回 ,找不到則傳回空字元串 。
- 擷取數組中的資料
- 可以通過中括号來通路數組中的資料
<%--擷取數組中的資料 --%> <% String [] provs = {"京","粵","滬","魯"}; pageContext.setAttribute("provs", provs); %> ${provs[2]}
- 可以通過中括号來通路數組中的資料
- 擷取集合中的資料
- 可以通過中括号來通路數組中的資料
<%--獲集合中的資料 --%> <% List list = new ArrayList(); list.add("孫悟空"); list.add("哈利波特"); list.add("薩達姆"); list.add("樸乾"); pageContext.setAttribute("list", list); %> ${list[3] }
- 可以通過中括号來通路數組中的資料
- 擷取Map中的資料
- 可以通過中括号或點的形式來擷取map中的資料 , 大部分情況下使用哪個都可以 , 但是如果擔心産生歧義(變量名中可能有點), 最好使用中括号
- 中括号中鍵的名稱加引号就是常量, 直接使用來擷取map中的值 , 如果不加引号 , 則是一個變量 , el會先去擷取對應的值 , 在根據其中的值擷取map中對應變量的值
<%--擷取map中的資料 --%> <% Map<String,String> map = new HashMap<String,String>(); map.put("name", "韋小寶"); map.put("addr", "揚州"); map.put("wife", "雙兒"); map.put("shifu", "陳近南"); map.put("wife.xiao","阿珂"); pageContext.setAttribute("map", map); pageContext.setAttribute("shifu", "addr"); %> ${map } ${map["name"] } ${map.wife } ${map["wife.xiao"] } ${map[shifu] }
- 擷取JavaBean的屬性
- 可以在el中通過【 bean的.屬性 】的方法來擷取bean中的屬性
- 要注意 ,前提是這個bean中必須要有對應的getxxx()方法
<%--擷取javabean的屬性 --%> <% Person p = new Person(); p.setName("張三豐"); p.setAge(120); p.setAddr("武當山"); pageContext.setAttribute("p", p); %> ${p.name } ${p.addr }
- 延伸~~
- pageContext來擷取目前應用的名稱
<%= request.getContextPath()%> ${pageContext.request.contextPath}
- pageContext來擷取目前應用的名稱
二、執行簡單的運算
- 算術運算
- +
- -
- *
- /
- %
<%--算數運算 --%> ${ 2 + 3 } ${ 2*3 } ${ 10/3 } ${ 2+"3" } <%-- ${ 2 + "a" } ${"a" + "b" } --%>
- 注意:el在進行算術運算時 , 會嘗試将參與運算的非數字字元轉換為數字參與運算 , 如果轉換不成功則直接抛出異常
- 注意:el執行算術運算時運算結果為double類型
- 關系運算
- == eq
- != ne
- < lt
- <= le
- > gt
-
= ge
<!--關系運算 --> ${3 == 4 } ${5>=3 }
- 邏輯運算
- && and
- || or
- ! not
<!--邏輯運算符 --> ${3>5 or 3<=4 } ${3>5 and 3<=4 } ${!(3>5 and 3<=4)}
- 三元運算
${3>2 ? "yes" : "no" }
- empty運算
- 判斷對象是否是null
- 判斷對象内容是否為空
- 判斷集合數組中是否沒有任何元素
- 判斷域中是否沒有任何屬性
<% String str = null; str = ""; str = "abc"; pageContext.setAttribute("str", str); List list = null; list = new ArrayList(); list.add("abc"); pageContext.setAttribute("list", list); request.setAttribute("like", "football"); %> ${empty str} ${empty list } ${empty requestScope} ${empty sessionScope} ${empty pageScope} ${empty applicationScope}
三、擷取常用開發對象
- 概述:
- 了為了友善使用 , 在其内部定義了11個el内置的對象 , 不需要 提親存入域中就能使用 。
- 要注意 , 着了所謂的11個内置對象域之jsp中九大飲食對象不是一回事 , 沒有關系
- 11個内置對象
- pageContext :代表目前頁面 , 有了它就意味着有了 九大隐式對象
<!-- pageContext 代表目前頁面的對象 有了它就相當于有了九大隐式對象 --> ${pageContext.request } ${pageContext.session }
- pageScope :pageContext域
- requestScope: request域
- sessionScope :session域
- applicationScope : application域
<!-- 代表四大作用域的對象,注意!是作用域 不是對象本身! pageScope -- pageContext域 requestScope -- request域 sessionScpoe -- sessiono域 applicationScope -- ServletContext域 --> <% request.setAttribute("name", "特朗普"); session.setAttribute("name", "普京"); application.setAttribute("name", "樸乾"); %> ${name } ${sessionScope.name } ${applicationScope.name }
- param : 浏覽器送出的請求所有參數組成的Map
- pageContext :代表目前頁面 , 有了它就意味着有了 九大隐式對象
四、調用函數
- 可以調用JSTL中fn子庫中的函數 , 在JSTL中詳解
- 可以調用自定義的函數 , 但是在開發中幾乎不用
(四)JSTL标簽
一、JSTL标簽概述
- JavaServer Pages Standard Tag Library 是提供給JavaWeb開發人員的一個标準通用的标簽函數庫
- 可以與EL表達式配合來取代傳統JSP頁面上嵌入大量的java代碼的做法 , 可以提高 程式的可讀性 、維護性 、 和友善性
- 在javaee4.0之前需要導入相關的jar包才能使用 ,但是在javaee5.0開始 , 預設已經包含了此jar包
- 在使用時需要在jsp頁面通過用<%@ taglib %> 标簽來引入相應的标簽庫
<%@ taglib uri="xxxx" prefix=""%> uri用來指定引入的包 prefix用于指定标簽的字首 ,可以是任意字元串, 在開發中一般使用預設的c 。
二、JSTL的子庫
- core : 核心标簽庫
- fn : JSTL提供的el函數庫 有很多可以通過el調用的函數
- fmt : 國際化标簽庫
- xml : 操作xml檔案的标簽庫
- sql : 操作sql的标簽庫
- 但是在開發中一般jsp檔案隻用來作資料的展示 , 而邏輯處理全部交給servlet , 是以xml子庫和sql子庫沒人用 , 國際化标簽fmt以後詳解。
三、core子庫
-
- 輸出常量
- 輸出變量
- 轉義輸出
- 輸出預設值
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <!DOCTYPE HTML> <html> <head> </head> <body> <h1>輸出固定值</h1> <c:out value="987"></c:out> <c:out value="abc"></c:out> ${987 } ${"abc" } <hr> <h1>輸出變量</h1> <% pageContext.setAttribute("name", "馬裡奧"); pageContext.setAttribute("name", "路易吉"); %> <c:out value="${name}"></c:out> ${name } <hr> <h1>轉義輸出</h1> <c:out value="<a href='#'>xxx</a>"></c:out> <c:out value="<a href='#'>xxx</a>" escapeXml="false"></c:out> ${fn:escapeXml("<a href='#'>xxx</a>") } <hr> <h1>輸出預設值</h1> <% pageContext.setAttribute("addr", "上海"); %> <c:out value="${addr}" default="北京"></c:out> ${addr == null ? "北京" : addr } <hr> </body> </html>
-
- 向四大作用域中添加域屬性
- 向map中添加或修改鍵值對
- 修改javaBean中的屬性
<%@page import="cn.tedu.Person"%> <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <h1>向四大作用域增加域屬性</h1> <c:set scope="request" var="name" value="張飛"></c:set> <c:set scope="page" var="name" value="關羽"></c:set> ${requestScope.name } ${pageScope.name } <hr> <h1>操作Map 增加或修改Map中的屬性</h1> <% Map map = new HashMap(); map.put("name", "劉備"); map.put("wife", "糜夫人"); pageContext.setAttribute("map", map); %> <c:set target="${map }" property="wife" value="孫尚香"></c:set> ${map } <c:set target="${map }" property="son" value="劉禅"></c:set> ${map } <hr> <h1>操作JavaBean的屬性</h1> <% Person p = new Person(); p.setName("諸葛亮"); p.setAge(20); p.setAddr("南陽"); pageContext.setAttribute("p", p); %> <c:set target="${p }" property="name" value="孔明"></c:set> ${p.name } <hr> </body> </html>
-
- 移除指定域中的指定名稱的屬性
- 如果不指定哪個域 , 則預設删除所有域中的該屬性
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE HTML> <html> <head> </head> <body> <h1>删除指定域中的屬性</h1> <% pageContext.setAttribute("name", "喬峰"); request.setAttribute("name", "段譽"); session.setAttribute("name", "虛竹"); application.setAttribute("name", "玄慈"); %> ${name } <c:remove var="name" scope="page"/> ${name } <c:remove var="name" scope="request"/> ${name } <c:remove var="name" scope="session"/> ${name } <c:remove var="name" scope="application"/> ${name } <hr> <h1>删除所有域中指定名稱的屬性</h1> <% pageContext.setAttribute("name", "喬峰"); request.setAttribute("name", "段譽"); session.setAttribute("name", "虛竹"); application.setAttribute("name", "玄慈"); %> <c:remove var="name"/> ${name } <hr> </body> </html>
-
- 捕捉指定範圍内的異常
- 捕獲到的異常可以通過聲明var屬性來指定一個名字 , 并自動寫入pageContext域中 , 以便後續處理
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <% try{ String str = null; str.toUpperCase(); }catch(Exception e){ out.write("哈哈哈 捕獲了異常~"); } %> <c:catch var="e"> <% String str = null; str.toUpperCase(); %> </c:catch> ${e } </body> </html>
-
- 實作判斷
- test寫判斷表達式
- scope聲明将判斷結果存入哪個域中
- var聲明存入域中時的變量名
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <h1>實作判斷</h1> <% int num = 1000; pageContext.setAttribute("num", num); %> <c:if test="${num<100}" scope="page" var="result"> yes~ </c:if> <c:if test="${num >= 100}"> no~ </c:if> ${result } <hr> </body> </html>
- -
- 實作多重判斷
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <% request.setAttribute("day", 2); %> <c:choose> <c:when test="${day == 1 }"> 星期一 </c:when> <c:when test="${day == 2 }"> 星期二 </c:when> <c:when test="${day == 3 }"> 星期三 </c:when> <c:when test="${day == 4 }"> 星期四 </c:when> <c:when test="${day == 5 }"> 星期五 </c:when> <c:otherwise> 休息日 </c:otherwise> </c:choose> </body> </html>
- 實作多重判斷
-
- 實作循環周遊 , 類似于java中的foe循環
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <h1>實作普通for循環</h1> <c:forEach begin="0" end="10" step="2" var="i"> ${i } </c:forEach> <hr> <h1>實作增強for循環</h1> <% List list = new ArrayList(); list.add("北京"); list.add("上海"); list.add("廣州"); list.add("深圳"); list.add("鐵嶺"); pageContext.setAttribute("list", list); %> <c:forEach items="${list }" var="addr"> ${addr } </c:forEach> <hr> <h1>實驗:周遊10到100的偶數,如果數字所在的位置是3的倍數,顯示成紅色</h1> <c:forEach begin="10" end="100" step="2" var="i" varStatus="stat"> <c:if test="${stat.count % 3 == 0 }"> <font color="red">${i }</font> </c:if> <c:if test="${stat.count % 3 != 0 }"> <font color="blue">${i }</font> </c:if> </c:forEach> <hr> </body> </html>
- 實作循環周遊 , 類似于java中的foe循環
-
- 将一串字元按照指定的字元切割
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <c:set scope="page" var="addr" value="www.tedu.cn"></c:set> ${addr } <br> <c:forTokens items="${addr }" delims="." var="x"> ${x } <br> </c:forTokens> </body> </html>
- 将一串字元按照指定的字元切割
-
- 實作url重寫 - 可以實作url重寫 , 在浏覽器禁用cookie時 , 在請求位址後加上jsessionid進而使用session
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML> <html> <head> </head> <body> <c:url var="addr" scope="page" value="/index.jsp" context="/Day14"></c:url> <a href="${addr }" target="_blank" rel="external nofollow" >xx</a> </body> </html>
- 實作url重寫 - 可以實作url重寫 , 在浏覽器禁用cookie時 , 在請求位址後加上jsessionid進而使用session
四、fn函數庫
- JSTL提供了 可以供el表達式調用的函數庫
- 其中提供了大量的操作字元串的函數
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <!DOCTYPE HTML> <html> <head> </head> <body> <c:set var="infos" value="${fn:split('www.tarena.com.cn','.') }" scope="page"></c:set> <c:forEach var="info" items="${infos }"> ${info }<br> </c:forEach> ${fn:toUpperCase("asdfasLKJasdfgLKjasdfgjk,lHJKqwertbnmassdfKL:HJ") } </body> </html>