- 論壇徽章:
- 0
|
JSP標(biāo)記學(xué)習(xí)筆記 itpride(原作)
關(guān)鍵字 JSP標(biāo)記
JSP標(biāo)記學(xué)習(xí)筆記
ginkou.fly 2002-9-18
1. 概述
1) 什么是JSP標(biāo)記
顧名思義,JSP標(biāo)記就是在JSP文件中使用的標(biāo)記。它類似于html語法中的標(biāo)記,像head 、table 。通過在JSP文件中引用它(就像使用html標(biāo)記那樣),可以更方便的實(shí)現(xiàn)對Java 代碼模塊的重用。
2) 為什么要使用JSP 標(biāo)記技術(shù)(與javabean相比)
好處:
J JSP 標(biāo)記可以處理JSP正文的內(nèi)容,比如改變文本顯示樣式;而javabean不可以。
J JSP標(biāo)記接口簡單,易于使用,也易于開發(fā)和維護(hù)。
壞處:
L JSP標(biāo)記在進(jìn)行設(shè)置時(shí)要比javabean復(fù)雜很多,體現(xiàn)在JSP標(biāo)記庫描述文件(*.tld)的配置上。
L JSP標(biāo)記實(shí)現(xiàn)的功能遠(yuǎn)不如javabean強(qiáng)大。
L 當(dāng)前只要JSP1.1支持JSP標(biāo)記,而JSP1.0和1.1都支持對Bean的使用。
2. SP標(biāo)記的開發(fā)簡介。
JSP標(biāo)記的開發(fā)需要編寫2種獨(dú)立的文件。一種是定義標(biāo)記功能的java類文件,一種是將xml元素名稱(標(biāo)記)映射到標(biāo)記實(shí)現(xiàn)的標(biāo)記庫描述符文件。
⑴ 編寫標(biāo)記處理程序類文件
需要繼承javax.servlet.jsp.tagext.TagSupport類;
簡單示例:
//文件名ExampleTag.java
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
public class ExampleTag extends TagSupport {
//程序的執(zhí)行起始點(diǎn)
public int doStartTag() {
try {
JspWriter out=pageContext.getOut();
out.print(“Custom tag example”);
}catch (IOException ioe) {
System.out.println(“Error in ExampleTag : “ + ioe);
}
return(SKIP_BODY); //當(dāng)標(biāo)記包括的內(nèi)容為空時(shí)返回SKIP_BODY,表示標(biāo)記功能
//已執(zhí)行完成
}
}
編譯好的class文件將位于服務(wù)器的的特定位置。
⑵ 編寫標(biāo)記庫描述符文件
將標(biāo)記名和其代表的功能實(shí)現(xiàn)聯(lián)系在一起。
簡單示例:
<!--文件名:csajsp-taglib.tld-->;
<? xml version=”1.0” encoding=”ISO-8859-1” ?>;
<!DOCTYPE taglib
PUBLIC “-//Sun Microsystem,Inc.//DTD JSP Tag Library 1.1//EN”
http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd>;
//以上是標(biāo)準(zhǔn)的文件頭
//以下是標(biāo)簽庫描述
<tlibversion>;1.0</tlibversion>; //Tag 庫的版本
<jspversion>;1.1</jspversion>; //Jsp 庫的版本
<shortname>;csajsp</shortname>;//自定義標(biāo)記前綴名
<uri>;</uri>; //標(biāo)記描述符文件的uri,可以是空
<info>;My custom tag!</info>; //標(biāo)記庫的描述信息
//以下定義新標(biāo)記
<tag>;
<name>;example</name>; //自定義的標(biāo)記名
<tagclass>;tags.ExampleTag</tagclass>;//定位標(biāo)簽處理類文件
<info>;Simplest example</info>;//描述信息
<bodycontent>;EMPTY</bodycontent>; // 不處理Jsp文件正文內(nèi)容
</tag>;
</taglib>;
此文件將配置在服務(wù)器的特定位置
⑶ 使用以上自定義的標(biāo)記
<!--文件名:simpleExample.jsp-->;
<!DOCTYPE HTML PUBLIC “- // W3C//DTD HTML 4.0 Transitional //EN”>;
<HTML>;
<HEAD>;
<%@ taglib uri = “csajsp-taglib.tld” prefix = “csajsp” %>; //進(jìn)行標(biāo)記使用聲明
<TITLE>;<csajsp:example />;<TITLE>;
<LINK REL=STYLESHEET HREF=”JSP-styles.css”
TYPE=”text/css”>;
<HEAD>;
<BODY>;
<H1>;<csajsp:example />;<H1>; /使用標(biāo)記
<csajsp:example />;
</BODY>;
</HTML>;
這樣最終在在瀏覽器上輸出為
Custom tag example
3. 深入的JSP標(biāo)記開發(fā)
⑴ 添加標(biāo)記屬性
在標(biāo)記處理類中可以通過函數(shù)setAttribute(String value) 為jsp標(biāo)記分配屬性,這樣標(biāo)記處理程序根據(jù)獲取的屬性值來實(shí)現(xiàn)相關(guān)功能。
比如 private String message = “Default Message”;
public void setMessage(String message) {
this.message=message;
}
注意:屬性名message是小寫的,設(shè)置函數(shù)中的Message是大寫的。
◆與之相關(guān)的在tld文件中需要在tag元素中添加如下元素
<tag>;
…
<attribute>;
<name>;message</name>; //屬性名
<required>;false</requied>; //屬性值是否必須提供。False表示不必,存在缺省值。
<rtexprvalue>;true</rtexprvalue>;//ture表示屬性值可以使用jsp表達(dá)式,false表示禁
//止使用
</attribute>;
…
</tag>;
◆對應(yīng)jsp文件中引用為:<prefix : name message = “ Hello!” />;
⑵ 使用標(biāo)記正文
即是在標(biāo)記中使用一些包含jsp腳本元素、文本等的內(nèi)容,這些內(nèi)容由jsp引擎處理。
形式如下:
<prefix : tagname>; body(正文內(nèi)容) <prefix : tagname>;
在處理jsp標(biāo)記的正文前,將會調(diào)用處理程序的doStartTag()方法,此時(shí)要在此方法中返回EVAL_BODY_INCLUDE 以表明包含有標(biāo)記正文;處理完后,將會調(diào)用doEndTag()方法,此后要讓jsp引擎繼續(xù)處理后面的頁面,得返回EVAL_PAGE,否則返回SKIP_PAGE。
◆對應(yīng)在tld文件中需要在tag元素中添加如下元素
<tag>;
…
<bodycontent>;JSP</bodycontent>; //表明包含正文
…
</tag>;
另外:可以設(shè)置一些條件來判斷是否包含正文的,如下:
public int doStartTag() {
ServletRequest request = pageContext.getRequest();
String debugFlag = request .getParameter(“debug”);
If ((debugFlag!=null) && (!debugFlag.equalsIgnoreCase(“false”))) {
Return (EVAL_BODY_INCLUDE);
}
else {
return(SKIP_BODY);
}
}
這樣只有在url尾部給出請求參數(shù)值debug = true,才會顯示標(biāo)記正文的內(nèi)容。這樣可以隱藏一些調(diào)試信息。
⑶ 對標(biāo)記正文進(jìn)行處理
jsp的標(biāo)記可以對包含的正文進(jìn)行處理(修改),然后再輸出。這需要標(biāo)記處理類繼承BodyTagSupport類(TagSupport類的繼承)。這個(gè)類提供了2個(gè)重要的方法用于正文處理。
→ doAfterBody:默認(rèn)執(zhí)行的方法,在此方法中包含正文的處理過程。
→ getBodyContent:返回BodyContent類型的的對象,此對象包含了有關(guān)標(biāo)記正文的信息。
BodyContent類型包含的重要方法:
→ getEnclosingWriter:返回JspWriter方法,輸出內(nèi)容。
→ getString:返回包含全部jsp標(biāo)記正文的字符串。
注意:這里和⑵中介紹的輸出jsp標(biāo)記正文的方式不一樣。前者的輸出是先由jsp引擎解釋,這里是在jsp標(biāo)記處理程序中直接輸出到給瀏覽器。
另外,在doAferBody中返回SKIP_BODY,表示終止標(biāo)記正文處理;若返回的是EVAL_BODY_TAG,將會再一次調(diào)用doAferBody方法,重新處理標(biāo)記正文,直到返回SKIP_BODY為止。
示例:
→標(biāo)記處理程序片:
//下面的程序片將調(diào)用一個(gè)filter方法,此方法用于把jsp正文中的字符< >; “ & 分別用&it; &gt; &guot; &amp;來代替。以使瀏覽器按字符原樣輸出,不進(jìn)行解釋。
public class FillterTag extends BodyTagSupport {
public int doAfterBody() {
BodyContent body=getBodyContent();
String filteredBody=ServletUtilities.filter(body.getString()); //將正文得到的字符串過濾
Try {
JspWriter out=body.getEnclosingWriter();
out.print(filteredBody); //輸出過濾后的文本
}catch(IOException ioe) {
System.out.println(“Error in FilterTag: “ + ioe);
}
return(SKIP_BODY); //終止jsp正文處理
}
→標(biāo)記符描述文件片
…
<tag>;
<name>;filter</name>;
<tagclass>;tags.FilterTag</tagclass>;
<bodycontent>;JSP</bodycontent>;
</tag>;
…
→jsp文件片
<csajsp:filter>;
<STRONG>;I love you!</STRONG>;
;
<EM>;I love you!<EM>;
</csajsp:filter>;
這樣,在瀏覽器中輸出的標(biāo)記正文應(yīng)當(dāng)是
<STRONG>;I love you!</STRONG>;
;
<EM>;I love you!<EM>;
而不是
I love you!
I love you!
、鞘褂胘sp嵌套標(biāo)記。
可以對多個(gè)JSP標(biāo)記進(jìn)行嵌套引用,這樣子標(biāo)記就可以訪問和存儲父標(biāo)記的數(shù)據(jù)和方法。
子標(biāo)記訪問父標(biāo)記需要使用BodyTagSupport類中的 findAccetorWithClass方法。注意它只能查找臨近的父標(biāo)記。
假如在jsp文件中如下的嵌套引用:
<!- - 此嵌套標(biāo)記模擬條件判斷- ->;
<csajsp:if>;
<csajsp:condition>;true</csajsp:condition>;
<csajsp:then>;Condition was true</csajsp:then>;
<csajsp:else>;Condition was false</csajsp:else>;
</csajsp:if>;
相應(yīng)的標(biāo)記處理程序片:
→對于if標(biāo)記,執(zhí)行類如下:
public class IfTag extends TagSupport {
private boolean condition ;
private Boolean hasCondition = flase ;
public void setCondition(Boolean condition) { //設(shè)置判斷條件的真假;condition子標(biāo)
//記調(diào)用
this.condition = condition ;
hasCondition = true ;
}
public Boolean getCondition() { //獲取判斷條件的真假then 、else子標(biāo)
//記調(diào)用
return(condition) ;
}
public void setHasCondition(Boolean flag) { //判斷if標(biāo)記后是否存在條件,由
//condition子標(biāo)記調(diào)用
this.hasCondition = flag ;
}
public Boolean getHasCondition() { //獲取是否存在判斷條件的信息,由
//then、else標(biāo)記調(diào)用
return(hasCondition) ;
}
public int doStartTag() {
return(EVAL_BODY_INCLUDE) //包含子標(biāo)記
}
}
→那么對于condition等其它子標(biāo)記的處理程序,需要獲取父標(biāo)記處理程序?qū)ο螅?br />
IfTag parent=(IfTag) findAncestorWithClass(this,IfTag.class)
之后就可以操作父標(biāo)記處理程序的相應(yīng)方法。
示例:(對于condition標(biāo)記)
public class IfConditionTag extends BodyTagSupport {
ifTag parent = (IfTag)findAncestorWithClass(this,IfTag.class); //獲取父標(biāo)記對應(yīng)的對象
If (parent = = null) {
Throw new JspTagException(“condition not inside it”);
}
return(EVAL_BODY_TAG);
}
public int doAfterBody() {
ifTag parent = (IfTag) findAncestorWithClass(this , IfTag.class) ;
String bodyString = getBodyContent() . getString() ;
If (bodyString.trim().equals(“true”)) {
Parent.setCondition(true) //訪問父標(biāo)記處理類中的方法
}else {
parent.setCondition(false) ;
}
return(SKIP_BODY) ;
}
}
其余標(biāo)記類和此相似。
4. 小結(jié)
對于一些不太復(fù)雜和功能單一的邏輯描述,需要傳遞的參數(shù)要求不高時(shí),使用JSP標(biāo)記,要方便的多。對于大多數(shù)的商業(yè)邏輯應(yīng)用,還是使用bean要好的多,也宜于servlet控制。
這個(gè)東東是俺學(xué)習(xí) 人郵 出的Servletlet與JSP核心技術(shù)》時(shí)隨手寫下的。里面的程序還沒具體配置過。過段時(shí)間弄了再搞篇實(shí)驗(yàn)體會吧。
|
|