JSP標(biāo)記學(xué)習(xí)筆記淺析
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相比)
好處:
JSP標(biāo)記可以處理JSP正文的內(nèi)容,比如改變文本顯示樣式;而javabean不可以。
JSP標(biāo)記接口簡單,易于使用,也易于開發(fā)和維護(hù)。
壞處:
JSP標(biāo)記在進(jìn)行設(shè)置時(shí)要比javabean復(fù)雜很多,體現(xiàn)在JSP標(biāo)記庫描述文件(*.tld)的配置上。
JSP標(biāo)記實(shí)現(xiàn)的功能遠(yuǎn)不如javabean強(qiáng)大。
當(dāng)前只要JSP1.1支持JSP標(biāo)記,而JSP1.0和1.1都支持對Bean的使用。
2.JSP標(biāo)記的開發(fā)簡介。
JSP標(biāo)記的開發(fā)需要編寫2種獨(dú)立的文件。一種是定義標(biāo)記功能的java類文件,一種是將xml元素名稱(標(biāo)記)映射到標(biāo)記實(shí)現(xiàn)的標(biāo)記庫描述符文件。
⑴編寫JSP標(biāo)記處理程序類文件
需要繼承javax.servlet.jsp.tagext.TagSupport類;
簡單示例:
- //文件名ExampleTag.java
- importjavax.servlet.jsp.*;
- importjavax.servlet.jsp.tagext.*;
- importjava.io.*;
- publicclassExampleTagextendsTagSupport{
- //程序的執(zhí)行起始點(diǎn)
- publicintdoStartTag(){
- try{
- JspWriterout=pageContext.getOut();
- out.print(“Customtagexample”);
- }catch(IOExceptionioe){
- System.out.println(“ErrorinExampleTag:“+ioe);
- }
- return(SKIP_BODY);//當(dāng)標(biāo)記包括的內(nèi)容為空時(shí)返回SKIP_BODY,表示標(biāo)記功能
- //已執(zhí)行完成
- }
- }
編譯好的class文件將位于服務(wù)器的的特定位置。
⑵編寫JSP標(biāo)記庫描述符文件
將標(biāo)記名和其代表的功能實(shí)現(xiàn)聯(lián)系在一起。
簡單示例:
- ﹤!--文件名:csajsp-taglib.tld--﹥;
- ﹤?xmlversion=”1.0”encoding=”ISO-8859-1”?﹥;
- ﹤!DOCTYPEtaglib
- PUBLIC“-//SunMicrosystem,Inc.//DTDJSPTagLibrary1.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﹥;Mycustomtag!﹤/info﹥;//標(biāo)記庫的描述信息
- //以下定義新標(biāo)記
- ﹤tag﹥;
- ﹤name﹥;example﹤/name﹥;//自定義的標(biāo)記名
- ﹤tagclass﹥;tags.ExampleTag﹤/tagclass﹥;//定位標(biāo)簽處理類文件
- ﹤info﹥;Simplestexample﹤/info﹥;//描述信息
- ﹤bodycontent﹥;EMPTY﹤/bodycontent﹥;//不處理JSP文件正文內(nèi)容
- ﹤/tag﹥;
- ﹤/taglib﹥;
此文件將配置在服務(wù)器的特定位置
⑶使用以上自定義的JSP標(biāo)記
- ﹤!--文件名:simpleExample.jsp--﹥;
- ﹤!DOCTYPEHTMLPUBLIC“-//W3C//DTDHTML4.0Transitional//EN”﹥;
- ﹤HTML﹥;
- ﹤HEAD﹥;
- ﹤%@tagliburi=“csajsp-taglib.tld”prefix=“csajsp”%﹥;//進(jìn)行標(biāo)記使用聲明
- ﹤TITLE﹥;﹤csajsp:example/﹥;﹤TITLE﹥;
- ﹤LINKREL=STYLESHEETHREF=”JSP-styles.css”
- TYPE=”text/css”﹥;
- ﹤HEAD﹥;
- ﹤BODY﹥;
- ﹤H1﹥;﹤csajsp:example/﹥;﹤H1﹥;/使用標(biāo)記
- ﹤csajsp:example/﹥;
- ﹤/BODY﹥;
- ﹤/HTML﹥;
這樣最終在在瀏覽器上輸出為
Customtagexample
3.深入的JSP標(biāo)記開發(fā)
⑴添加標(biāo)記屬性
在標(biāo)記處理類中可以通過函數(shù)setAttribute(Stringvalue)為JSP標(biāo)記分配屬性,這樣標(biāo)記處理程序根據(jù)獲取的屬性值來實(shí)現(xiàn)相關(guān)功能。
比如:
- privateStringmessage=“DefaultMessage”;
- publicvoidsetMessage(Stringmessage){
- 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:namemessage=“Hello!”/﹥;
⑵使用標(biāo)記正文
即是在標(biāo)記中使用一些包含JSP腳本元素、文本等的內(nèi)容,這些內(nèi)容由JSP引擎處理。
形式如下:
﹤prefix:tagname﹥;body(正文內(nèi)容)﹤prefix:tagname﹥;
在處理JSP標(biāo)記的正文前,將會(huì)調(diào)用處理程序的doStartTag()方法,此時(shí)要在此方法中返回EVAL_BODY_INCLUDE以表明包含有標(biāo)記正文;處理完后,將會(huì)調(diào)用doEndTag()方法,此后要讓jsp引擎繼續(xù)處理后面的頁面,得返回EVAL_PAGE,否則返回SKIP_PAGE。
◆對應(yīng)在tld文件中需要在tag元素中添加如下元素
- ﹤tag﹥;
- …
- ﹤bodycontent﹥;JSP﹤/bodycontent﹥;//表明包含正文
- …
- ﹤/tag﹥;
另外:可以設(shè)置一些條件來判斷是否包含正文的,如下:
- publicintdoStartTag(){
- ServletRequestrequest=pageContext.getRequest();
- StringdebugFlag=request.getParameter(“debug”);
- If((debugFlag!=null)&&(!debugFlag.equalsIgnoreCase(“false”))){
- Return(EVAL_BODY_INCLUDE);
- }
- else{
- return(SKIP_BODY);
- }
- }
這樣只有在url尾部給出請求參數(shù)值debug=true,才會(huì)顯示標(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,將會(huì)再一次調(diào)用doAferBody方法,重新處理標(biāo)記正文,直到返回SKIP_BODY為止。
示例:
→標(biāo)記處理程序片:
下面的程序片將調(diào)用一個(gè)filter方法,此方法用于把JSP正文中的字符﹤﹥;“&分別用⁢>&guot;&來代替。以使瀏覽器按字符原樣輸出,不進(jìn)行解釋。
- publicclassFillterTagextendsBodyTagSupport{
- publicintdoAfterBody(){
- BodyContentbody=getBodyContent();
- StringfilteredBody=ServletUtilities.filter(body.getString());//將正文得到的字符串過濾
- Try{
- JspWriterout=body.getEnclosingWriter();
- out.print(filteredBody);//輸出過濾后的文本
- }catch(IOExceptionioe){
- System.out.println(“ErrorinFilterTag:“+ioe);
- }
- return(SKIP_BODY);//終止JSP正文處理
- }
→標(biāo)記符描述文件片
- …
- ﹤tag﹥;
- ﹤name﹥;filter﹤/name﹥;
- ﹤tagclass﹥;tags.FilterTag﹤/tagclass﹥;
- ﹤bodycontent﹥;JSP﹤/bodycontent﹥;
- ﹤/tag﹥;
- …
→JSP文件片
- ﹤csajsp:filter﹥;
- ﹤STRONG﹥;Iloveyou!﹤/STRONG﹥;
- ;
- ﹤EM﹥;Iloveyou!﹤EM﹥;
- ﹤/csajsp:filter﹥;
這樣,在瀏覽器中輸出的標(biāo)記正文應(yīng)當(dāng)是
- ﹤STRONG﹥;Iloveyou!﹤/STRONG﹥;
- ;
- ﹤EM﹥;Iloveyou!﹤EM﹥;
而不是
Iloveyou!
Iloveyou!
⑶使用JSP嵌套標(biāo)記。
可以對多個(gè)JSP標(biāo)記進(jìn)行嵌套引用,這樣子標(biāo)記就可以訪問和存儲(chǔ)父標(biāo)記的數(shù)據(jù)和方法。
子標(biāo)記訪問父標(biāo)記需要使用BodyTagSupport類中的findAccetorWithClass方法。注意它只能查找臨近的父標(biāo)記。
假如在JSP文件中如下的嵌套引用:
- ﹤!--此嵌套標(biāo)記模擬條件判斷--﹥;
- ﹤csajsp:if﹥;
- ﹤csajsp:condition﹥;true﹤/csajsp:condition﹥;
- ﹤csajsp:then﹥;Conditionwastrue﹤/csajsp:then﹥;
- ﹤csajsp:else﹥;Conditionwasfalse﹤/csajsp:else﹥;
- ﹤/csajsp:if﹥;
- 相應(yīng)的標(biāo)記處理程序片:
- →對于if標(biāo)記,執(zhí)行類如下:
- publicclassIfTagextendsTagSupport{
- privatebooleancondition;
- privateBooleanhasCondition=flase;
- publicvoidsetCondition(Booleancondition){//設(shè)置判斷條件的真假;condition子標(biāo)
- //記調(diào)用
- this.condition=condition;
- hasCondition=true;
- }
- publicBooleangetCondition(){//獲取判斷條件的真假then、else子標(biāo)
- //記調(diào)用
- return(condition);
- }
- publicvoidsetHasCondition(Booleanflag){//判斷if標(biāo)記后是否存在條件,由
- //condition子標(biāo)記調(diào)用
- this.hasCondition=flag;
- }
- publicBooleangetHasCondition(){//獲取是否存在判斷條件的信息,由
- //then、else標(biāo)記調(diào)用
- return(hasCondition);
- }
- publicintdoStartTag(){
- return(EVAL_BODY_INCLUDE)//包含子標(biāo)記
- }
- }
→那么對于condition等其它子標(biāo)記的處理程序,需要獲取父標(biāo)記處理程序?qū)ο螅?/P>
IfTagparent=(IfTag)findAncestorWithClass(this,IfTag.class)
之后就可以操作父標(biāo)記處理程序的相應(yīng)方法。
示例:(對于condition標(biāo)記)
- publicclassIfConditionTagextendsBodyTagSupport{
- ifTagparent=(IfTag)findAncestorWithClass(this,IfTag.class);//獲取父標(biāo)記對應(yīng)的對象
- If(parent==null){
- ThrownewJspTagException(“conditionnotinsideit”);
- }
- return(EVAL_BODY_TAG);
- }
- publicintdoAfterBody(){
- ifTagparent=(IfTag)findAncestorWithClass(this,IfTag.class);
- StringbodyString=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)體會(huì)吧。
以上就是JSP標(biāo)記學(xué)習(xí)筆記,希望對于初學(xué)者有所幫助,對你的開發(fā)有一定的引導(dǎo)。
【編輯推薦】