WEB-JSP概述-2- JSP指令-標籤技術

1.1. JSP指令

1.1.1. page指令

用來通知翻譯引擎,如何翻譯當前的JSP

[ language="java" ]當前JSP使用的開發語言

[ extends="package.class" ]當前jsp翻譯成servlet後要繼承的類,注意此值必須是一個servlet的子類,一般情況下不要改

[ import="{package.class | package.*}, ..." ]導入需要使用到的包 java.lang.*;javax.servlet.*;javax.servlet.jsp.*;javax.servlet.http.*;

[ session="true | false" ]用來指定當前頁面是否使用session,如果設置爲true,則翻譯過來的servlet中將會有對session對象的引用,於是可以直接在jsp中使用session隱式對象。但是這將導致一旦訪問jsp就會調用request.getSession()方法,可能導致不必要的空間浪費。如果確定jsp中不需要session可以設爲false

[ buffer="none | 8kb | sizekb" ] out隱式對象所使用的緩衝區的大小

[ autoFlush="true | false" ] out隱式對象是否自動刷新緩衝區,默認爲true,不需要更改

[ isThreadSafe="true | false" ]翻譯過來的servlet是否實現SingleThreadModel

[ errorPage="relative_url" ]如果頁面出錯,將要跳轉到的頁面,除了在jsp中使用此屬性指定錯誤頁面外也可以在web.xml中配置整個web應用的錯誤頁面,如果兩個都設置則jsp中的此屬性起作用

[ isErrorPage="true | false" ]如果設置此屬性爲true,翻譯過來的servlet中將含有Exception隱式對象,其中封裝的就是上一個頁面中拋出的異常對象

[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ]jsp亂碼相關的指令,用來指定jsp輸出時,設置的Content-Type響應頭用來指定瀏覽器打開的編碼

[ pageEncoding="characterSet | ISO-8859-1" ]服務器翻譯jsp時使用的編碼集.如果向防止jsp亂碼,應該保證文件的保存編碼和jsp翻譯成servlet用的編碼以及輸出到瀏覽器後瀏覽器打開的編碼一致.此屬性一旦設置好,翻譯引擎會間接幫我們設置content-type屬性.

[ isELIgnored="true | false" ]當前頁面是否使用el表達式,設置爲false時表示啓用el,j2ee4.0開始默認支持,j2ee4.0一下做開發時,如果要使用el表達式,需將此屬性設置爲fals

 

1.1.2. include指令

<%@ incluede file=""%>靜態引入其他頁面的內容

*靜態引入:

在源文件級別進行合併,多個jsp生成一個servlet,最終由這一個servlet生成響應。推薦使用。

*動態引入:

在運行時將多個輸出進行合併,多個jsp分別生成多個servlet,最終由這多個servlet生成響應,組成一個輸出流,提供響應。執行效率沒有靜態引入高。

1.1.3. taglib指令

<%@ taglib uri="" prefix=""%>用來引入標籤庫。

uri指定被引入.tld文件的名稱空間

prefix 對該名稱空間的一個縮寫

1.2. 九大隱式對象

1.2.1九大隱式對象概述


jsp翻譯成Serlvet時,jsp翻譯引擎在翻譯過來的Serlvet中,預先定義了一些變量,可以不需要在JSP中預先定義就可以直接使用,共有9個,統稱爲jsp的九大隱式對象。分別是:

page

config

application

response

request

session

out

exception

pageContext

其中其他的七個我們都學習過了,只需要再學習一下outpageContext即可。

1.2.2. out對象


可以將他理解成response.getWriter()獲得的PrintWriter.

它自帶一個緩衝區,其大小收page指令中的buffer的設定限制。當緩衝區滿或緩衝區被關閉或當前jsp頁面結束,則此緩衝區中的內容將被刷新到response.getWriter()的緩衝區中。

1.2.3. PageContext對象


(1)作爲入口對象獲取其它八大隱式對象。

getException方法返回exception隱式對象

getPage方法返回page隱式對象

getRequest方法返回request隱式對象

getResponse方法返回response隱式對象

getServletConfig方法返回config隱式對象

getServletContext方法返回application隱式對象

getSession方法返回session隱式對象

getOut方法返回out隱式對象

(2)作爲入口對象獲取其他域中的數據

pageContext操作所有域中屬性的方法

getAttribute(String name,int scope)

setAttribute(String name, Object value,int scope)

removeAttribute(String name,int scope)

其中pageContext中代表域的常量:

PageContext.APPLICATION_SCOPE

PageContext.SESSION_SCOPE

PageContext.REQUEST_SCOPE

PageContext.PAGE_SCOPE

findAttribute方法:

在四大域中搜尋屬性,搜尋的順序是page域、request域、session域、application域,從小域到大域開始搜索,如果搜索到就直接獲取該值,如果所有域中都找不到,返回一個null

(3)作爲域對象使用

作用的範圍:真個jsp頁面,是四大作用域中最小的一個。

生命週期:當對jsp的請求開始時生成,當響應結束時銷燬。

作用:在jsp頁面範圍內共享數據

 

(4)跳轉到其他資源

其身上提供了forward



2. JSP標籤技術概述

1.1. Jsp標籤技術概述

1.1.1. JSP標籤技術概述

在之前我們編寫的程序中,JSP頁面中大量的寫入了java代碼,我們發現在jsp頁面中嵌入大量java代碼會造成頁面的可讀性、可維護性下降。

如圖-1所示:

 

-1

那麼該如何解決這種問題呢?sun公司考慮到這種問題,爲我們提供了JSP標籤技術,通過標籤替換掉jsp頁面中的java代碼,從而提高jsp頁面的可讀性、可維護性。

JSP中的標籤技術我們介紹如下四種:

JSP標籤

EL表達式

JSTL標籤

自定義標籤

2. JSP標籤

2.1. JSP標籤詳解

2.1.1. JSP標籤詳解

sun公司提供,屬於jsp規範中的內容,不需要引入第三方標籤庫,我們介紹其中的三個。

<jsp:inclue>用來替代request.getRequestDispatcher().include()

<jsp:forward>用來替代request.getRequestDispatcher().forward()

<jsp:param>配合前兩個標籤使用,可以在包含或轉發時,帶一些參數過去

3. el表達式

3.1. EL概述

3.1.1. EL概述

EL 全名爲Expression Language,用來替代<%=  %>腳本表達式。

j2ee4.0以前默認是不支持el,如果需要需要指定page指令[isELIgnored="true | false" ]falseJ2EE4.0後默認支持el

EL具有獲取數據、執行運算、獲取常用開發對象、調用java方法這四方面的功能

3.2. 獲取數據

3.2.1. 獲取常量

EL支持數據、字符串、布爾類型的常量

${23}

${“asdf”}

${true}

3.2.2. 獲取變量:在四大作用域中搜尋屬性

${propName}在四個域中搜尋proName屬性,輸出該值到輸出流中

搜尋域的順序爲由小到大。

如果四大域中都搜尋不到,則什麼都不輸出。

3.2.3. 獲取變量:獲取指定域中的屬性

${pageScope/requestScope/sessionScope/applicationScope.proName}

獲取指定域中的屬性

3.2.4. 獲取變量:獲取數組中的數據

${attr[0]}獲取域中的數組的指定元素

3.2.5. 獲取變量:獲取集合中的數據

${list[0]}獲取list中的指定位置元素

3.2.6. 獲取變量:獲取map中的數據

${map.keyName}獲取map中指定鍵的值

3.2.7. 獲取變量:獲取javabean屬性

${bean.propName}獲取javaBean的屬性,可以認爲是調用了javaBeangetXXX方法,

最重要的一個應用場景:

在寫路徑的時候最好不要把web應用名稱寫死,java中應該用request.getContextPath去獲取,jsp中就用el獲取:

${pageContext.request.contextPth}

3.2.8. 獲取數據細節

1)和[]區別:使用點的地方都可以用中括號,如果屬性名是數字或包含特殊符號(.-)就必須使用中括號。例子:${map["first.name"]}

2EL只能獲取不能設置

3EL只能獲取不能遍歷

3.3. 進行簡單運算

3.3.1. 算數運算

${3+2}

${“3”+2}

${“3”+2}

${1+”a”}

所有參與元算的元素都會被轉成數字,如果不能轉就報錯,空元素參與運算當作沒參與。

3.3.2. 關係運算:

如圖-2所示:

 

-2

${3 > 2}  

${3 gt 2}

3.3.3. 邏輯運算:

如圖-3所示:

 

-3

${3>2 && 4>5}

3.3.4. Empty運算符

empty/not empty判斷對象是否爲null,判斷集合是否爲空,數組長度是否爲0,判斷字符串是否爲空串,判斷域中是否沒有任何屬性。

3.3.5. 三元表達式

${name == null ? "張三" : name;}

3.4. 獲取web開發常用對象

3.4.1. EL的內置對象

El中預先定義了11個內置對象,不需要提前存入域中個,可以直接在el使用。

如圖-4、圖-5所示:

 

-4

 

-5

3.4.2. pageContext

代表pageContext對象,通過他可以獲取其他八大隱式對象

3.4.3. 四大作用域中域屬性組成的map

pageScope:代表page域,可以用來獲取page域中的屬性

reqeustScope:代表reqeust域,可以用來獲取reqeust域中的屬性

sessionScope:代表session域,可以用來獲取session域中的屬性

applicationScope:代表application域,可以用來獲取application域中的屬性

3.4.4. 請求參數組成的map

param 代表請求參數組成的map集合${param.userName}

paramValues 代表請求參宿組成的map集合,但是此集合的valueString[],用來獲取一名多值的param

3.4.5. 請求頭組成的map

header 獲取請求頭組成的map

headerValues 獲取請求頭組成的map但是value是一個String[],用來獲取一名多值的head

3.4.6. 所有cookie信息組成的map

cookie :獲取cookie組成的map對象,鍵爲cookie的名,值爲Cookie對象。

${cookie.cookieName.cookieValue}

3.4.7. web應用初始化參數組成的map

initParam map封裝的web.xml中配置的整個web應用的初始化參數

3.5. 調用java方法

3.5.1. 調用java方法

略。

4. JSTL標籤庫

4.1. JSTL標籤庫概述

4.1.1. JSTL標籤庫概述

JSTL全稱爲JavaServer Pages Standard Tag Library

JCPJava Community Process)指定標準

是提供給 Java Web 開發人員一個標準通用的標籤函數庫

可以和 EL 配合來取代傳統直接在頁面上嵌入 Java 程序(Scripting)的做法,以提高程序可讀性、維護性和方便性

javaee4.0需要導入JSTL相關的jar包,在javaee5.0開始,默認已經包含了此jar包。還要需要用<%@taglib%>指令引入標籤庫

4.2. JSTL標籤庫子庫

4.2.1. JSTL標籤庫子庫

核心標籤庫 (core)  --- c

國際化標籤 fmt

數據庫標籤 sql --Servlet

XML標籤  xml

JSTL函數(EL函數) el

4.3. JSTL核心標籤庫

4.3.1. <c:out>

如圖-6所示:

 

-6

輸出固定值 <c:out value="Hello c out~"/> 輸出變量 <c:out value="${m}"/> 轉義html,默認爲轉義,可以設置escapeXml屬性爲false,禁止轉義 <c:out value="<a href='#'>link</a>" escapeXml="false"/> 允許輸出默認值,如果給定值不存在,輸出默認值 <c:out value="${city}" default="北京"/>

4.3.2. <c:set>

如圖-7所示:

 

-7

標籤用於把某一個對象存在指定的域範圍內,或者設置Web域中的java.util.Map類型的屬性對象或JavaBean類型的屬性對象的 屬性。

在指定域中增加、修改屬性<c:set var="name" value="value" scope="page"/>設置一個保存在四個範圍的java對象的屬性值,cset不能設置對象進域,但是可以更改域中對象的屬性<c:set targe="${person}" property="name" value="lisi"/>  

4.3.3. <c:remove>

標籤用於刪除各種Web域中的屬性

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

4.3.4. <c:catch>

標籤用於捕獲嵌套在標籤體中的內容拋出的異常,其語法格式如下:

<c:catch var="e"> <% String s = null; s.charAt(1);    %> </c:catch>

4.3.5. <c:if>

如圖-8所示:

 

-8

此標籤可以構造簡單的if-then”結構的條件表達式 。

4.3.6. <c:choose>

標籤用於指定多個條件選擇的組合邊界,它必須與<c:when><c:otherwise>標籤一起使用。使用<c:choose><c:when><c:otherwise>三個標籤,可以構造類似 “if-else if-else” 的複雜條件判斷結構。

<c:choose> <c:when test="${weekday==1}"> 星期一 </c:when> <c:when test="${weekday==1}"> 星期二 </c:when> <c:when test="${weekday==1}"> 星期三 </c:when> <c:otherwise> 輸入無效 </c:otherwise> </c:choose>

4.3.7. <c:forEach>

標籤用於對一個集合對象中的元素進行循環迭代操作,或者按指定的次數重複迭代執行標籤體中的內容。

如圖-9所示:

 

-9

varStatus屬性,如圖-10所示:

 

-10

實驗:遍歷10100的偶數,如果數字所在的位置是3的倍數,顯示成紅色

4.3.8. <c:forTokens>

用來瀏覽一字符串中所有的成員,其成員是由定義符號所分隔的

4.3.9. <c:param>

JSP頁面進行URL的相關操作時,經常要在URL地址後面附加一些參數。<c:param>標籤可以嵌套在<c:import><c:url><c:redirect>標籤內,爲這些標籤所使用的URL地址附加參數。

4.3.10. <c:import>

標籤,實現include操作,如圖-11所示:

 

-11

4.3.11. <c:url>

如圖-12所示:

 

-12

標籤用於在JSP頁面中構造一個URL地址,其主要目的是實現URL重寫。URL重寫就是將會話標識號以參數形式附加在URL地址後面

4.3.12. <c:redirect>

此標籤用於實現請求重定向。如圖-13所示:


-13

5. 自定義標籤技術

5.1. 自定義標籤概述

5.1.1. 自定義標籤概述

雖然有第三方組織提供了很多標籤,但是這些都是一些通用標籤,開發中常常需要根據業務需求使用jsp頁面,這個時候通用的標籤就不夠用了,我們需要自己去開發標籤庫。

5.2. 開發自定義標籤

5.2.1. 開發步驟

想要開發自定義標籤需要兩個步驟:

寫一個類實現SimpleTag接口

tld文件中描述該標籤,在jsp頁面中通過<%@taglib %>引入該標籤庫使用標籤

5.3. 寫一個類實現SimpleTag接口

5.3.1. 寫一個類實現SimpleTag接口

SimpleTag接口的繼承結構如圖-14所示:

 

-14

我們寫一個類實現SimpleTag接口,發現其中包含如下方法:

public void doTag() throws JspException, IOException {

 

}

 

public void setParent(JspTag parent) {

 

}

 

public JspTag getParent() {

return null;

}

 

public void setJspContext(JspContext pc) {

 

}

public void setJspBody(JspFragment jspBody) {

 

}

5.3.2. SimpleTag接口方法詳解

jsp頁面執行到自定義標籤時,首先創建出自定義標籤處理類對象,創建出來後會立即調用setJspContext方法將當前頁面的PageContext傳入。如果當前標籤具有標籤體,則將標籤的標籤體封裝到JspFragment對象中調用setJspBody方法,如果沒有標籤體此方法不執行。如果當前自定義標籤有父標籤,則調用setParent方法將父標籤傳入。最後調用doTag方法執行自定義標籤的處理邏輯。

所以我們在開發自定義標籤時,將核心代碼寫入doTag方法即可。

更多的時候我們不會直接實現SimpleTag接口而是繼承SimpleTagSupport

SimpleTagSupport實現了SimpleTag接口,對立面的方法都做了實現,實現了setJspContext方法,將JspContext保存成了類的成員,並提供了getJspContext()方法獲取該對象。實現了setJspBody(JspFragment)方法,將JspFragment保存成了類的成員,並提供了getJspBody()方法獲取該對象。實現了doTag方法,做了空實現,我們作爲實現類,只需要覆蓋這個方法,在其中編寫標籤處理代碼。

 

5.4. 實現自定義標籤的基本功能

5.4.1. 控制是否執行標籤體

控制標籤體不執行:什麼都不做標籤體默認就不執行

控制標籤體執行:獲取封裝了標籤體的JSPFragment對象,執行invoke方法,輸出到out輸出流中即可

JspFragment fragment = this.getJspBody();

fragment.invoke(this.getJspContext().getOut());

fragment.invoke(null);

5.4.2. 控制是否執行標籤之後的內容

控制標籤之後的內容執行:什麼都不做,就執行

控制標籤之後的內容不執行:拋出一個特殊的異常SkipPageException就可以阻止標籤之後的內容執行

throw new SkipPageException();

5.4.3. 控制標籤體重複執行

JspFragment fragment = this.getJspBody();

for(int i = 0;i<5 ;i++){

fragment.invoke(null);

}

5.4.4. 修改標籤體輸出

StringWriter writer = new StringWriter();

JspFragment fragment = this.getJspBody();

fragment.invoke(writer);

String str = writer.toString();

str = str.toUpperCase();

this.getJspContext().getOut().write(str);

5.5. tld文件中描述該標籤

5.5.1. tld文件詳解

tld是專門用來描述自定義標籤的文件,可以在其中描述自定義標籤。

tld文件必須放置在WEB-INF目錄除classeslib目錄外的其他目錄下。

其格式如下,如圖-15所示:

 

-15

其中<name>是該自定義標籤的名字

<tag-class>是該自定義標籤處理類的全路徑名

<body-content>是標籤體類型,可取的值爲Empty表示不能含有標籤體。scriptless表示可以包含標籤體但是不能包含java源代碼。JSP表示可以包含任意內容的標籤體。

5.6. jsp頁面中引入自定義標籤使用

5.6.1. jsp頁面中引入自定義標籤

jsp頁面中使用<%@taglib %>引入自定義標籤。

<%@ taglib uri="http://www.easymall.com/myTag" prefix="myTag" %>

5.7. 開發帶有屬性的自定義標籤

5.7.1. 開發帶有屬性的自定義標籤

想要開發帶有屬性的標籤,需要做如下兩件事:

在自定義標籤處理類中定義javabean屬性並提供setXxx()方法,如圖-16所示:

 

-16

tld文件中描述該屬性,如圖-17所示:

 

-17

其中,描述屬性的標籤如圖-18所示:

 

-18

5.8. 打包自定義標籤爲jar

5.8.1. 打包自定義標籤爲jar

略。

6. JSTL+EL改造註冊、登錄頁面

6.1. login.jsp

6.1.1. 改造login.jsp

之前的代碼十分混亂,如圖-19所示:

 

-19

el+jstl改造,如圖-20所示:

 

-20

6.1.2. 自定義標籤實現URL解碼

經過測試發現顯示的用戶名是經過URL編碼的,而JSTL並沒有提供現成的URL解碼用的標籤,而我們不希望在jsp頁面中寫java代碼,對於這種非常常見的功能,我們可以開發一個自定義標籤來進行處理。代碼如圖-21所示:

 

-21

tld文件中描述該標籤,如圖-22所示:

 

-22

regist.jsp中引入此tld文件,通過該自定義標籤進行URL解碼,如圖-23所示:

 

-23

經過測試,可以正確的顯示中文,如圖-24所示:

 

-24

6.2. index.jsp

6.2.1. 改造index.jsp

如圖-25所示:

 

-25

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章