明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

servlet2.3(續(xù))

[摘要]標(biāo)記庫(kù) 新的規(guī)范中幾個(gè)有關(guān)標(biāo)記庫(kù)的概念得到了澄清,而且規(guī)范的許多地方作了整理。對(duì)于標(biāo)記庫(kù),新的規(guī)范還有一個(gè)重要的補(bǔ)充——迭代(iterator)標(biāo)記。在當(dāng)前的JSP 1.1規(guī)范中,如果標(biāo)記要執(zhí)行“循...
標(biāo)記庫(kù)
新的規(guī)范中幾個(gè)有關(guān)標(biāo)記庫(kù)的概念得到了澄清,而且規(guī)范的許多地方作了整理。對(duì)于標(biāo)記庫(kù),新的規(guī)范還有一個(gè)重要的補(bǔ)充——迭代(iterator)標(biāo)記。在當(dāng)前的JSP 1.1規(guī)范中,如果標(biāo)記要執(zhí)行“循環(huán)”它就必須是一個(gè)BodyTag。然而,標(biāo)記可能不必處理它的標(biāo)記體,定義BodyTag導(dǎo)致容器生成效率低下的代碼(setBodyContent()和其他一些方法仍將被調(diào)用)。為解決這個(gè)問(wèn)題,JSP 1.2引入了迭代標(biāo)記。

JSP 1.2規(guī)范引入了兩個(gè)新的常量,即EVAL_BODY_BUFFERED和EVAL_BODY_AGAIN。EVAL_BODY_BUFFERED作為一個(gè)具有更明確含義的名字取代EVAL_BODY_TAG,兩者的值是一樣的。它意味著以前編寫的代碼仍舊可以運(yùn)行。另外,它也意味著現(xiàn)在實(shí)現(xiàn)doStartTag()時(shí)應(yīng)該返回EVAL_BODY_BUFFERED而不是EVAL_BODY_TAG。

EVAL_BODY_AGAIN也有與EVAL_BODY_BUFFERED同樣的值,但它的名字同樣具有更明確的含義。當(dāng)標(biāo)記想要讓容器迭代(即反復(fù)執(zhí)行)它的標(biāo)記體時(shí)doAfterBody()方法應(yīng)該返回這個(gè)值。

javax.servlet.jsp.IterationTag是JSP 1.2規(guī)范定義的新接口,要定義迭代行為就必須實(shí)現(xiàn)這個(gè)接口。IterationTag接口擴(kuò)展SimpleTag并增加了一個(gè)doAfterBody()方法,BodyTag現(xiàn)在從IterationTag而不是SimpleTag繼承。

實(shí)現(xiàn)迭代時(shí),在BodyTag或者IterationTag中,doAfterBody()方法應(yīng)該返回EVAL_BODY_AGAIN以強(qiáng)制容器再次執(zhí)行標(biāo)記,返回SKIP_BODY則終止迭代。為IterationTag編寫的代碼很簡(jiǎn)單,如Listing 5所示。


【Listing 5】

public class SimpleIterator extends TagSupport implements IterationTag {
int loopCount;
}
public void setLoopCount(int loopCount) {
this.loopCount = loopCount;
}

public int doStartTag() {
return EVAL_BODY_INCLUDE;
}

public int doAfterBody() {
while(--loopCount > 0) return EVAL_BODY_AGAIN;
return SKIP_BODY;
}
}

  doStartTag()返回EVAL_BODY_INCLUDE,doAfterBody()返回EVAL_BODY_AGAIN以實(shí)現(xiàn)迭代,迭代完成時(shí)則返回SKIP_BODY。注意當(dāng)前還沒(méi)有與TagSupport、BodyTagSupport相配的IterationTagSupport類,不過(guò)這并不會(huì)真正帶來(lái)什么麻煩。

  標(biāo)記庫(kù)的當(dāng)前版本支持非常有限的合法性檢驗(yàn)機(jī)制。TagExtraInfo類里面可以定義一個(gè)isValid方法,這個(gè)方法在頁(yè)面編譯的時(shí)候被調(diào)用,你可以用它檢查屬性名字、值、類型等。JSP 1.2規(guī)范提供了更強(qiáng)大的合法性檢驗(yàn)機(jī)制。你可以定義一個(gè)檢驗(yàn)器類,在它里面定義一個(gè)方法,這個(gè)方法通過(guò)參數(shù)得到包含標(biāo)記庫(kù)內(nèi)一個(gè)或者多個(gè)標(biāo)記的整個(gè)頁(yè)面的XML描述,參見Listing 6的實(shí)例。這個(gè)方法在編譯頁(yè)面的時(shí)候被調(diào)用(它是一次性的調(diào)用。也就是說(shuō),你只付出一次調(diào)用的代價(jià),而不是每次用戶請(qǐng)求頁(yè)面的時(shí)候都要調(diào)用)。


【Listing 6】

public class SimpleIteratorValidator extends TagLibraryValidator {

public String validate( String prefix, String uri, PageData page) {
java.io.InputStream is = page.getInputStream();
boolean b = validateJSP(is);

// 一切正常
if(b) return null;
 else return "Some Validation Error";
}
}

Listing 6的檢驗(yàn)器擴(kuò)展了javax.servlet.jsp.tagext.TagLibraryValidator,而且它覆蓋了validate()。validate()方法的參數(shù)中傳入了待檢驗(yàn)標(biāo)記的前綴以及相關(guān)的URI。第三個(gè)參數(shù)PageData允許你訪問(wèn)一個(gè)InputStream,這個(gè)InputStream包含XML格式的JSP頁(yè)面。如果一切正常,validate方法返回null;如果檢驗(yàn)不能通過(guò),則它返回一個(gè)錯(cuò)誤字符串。注意這是一個(gè)在頁(yè)面編譯時(shí)出現(xiàn)的錯(cuò)誤,它只可能在開發(fā)階段出現(xiàn)。

新的規(guī)范還涉及了其他一些問(wèn)題。例如,JSP 1.2規(guī)范最終將定義一個(gè)JSP頁(yè)面的XML描述。JSP頁(yè)面的XML描述不僅對(duì)合法性檢驗(yàn)很有用(如上面例子所示),而且對(duì)于工具軟件供應(yīng)商來(lái)說(shuō)也很有用,因?yàn)樗?jiǎn)化了JSP編輯器的開發(fā)。

新的JSP規(guī)范還允許我們把監(jiān)聽器定義成標(biāo)記,而不是本文前面所出現(xiàn)的獨(dú)立的類。JSP規(guī)范現(xiàn)在包含了一章關(guān)于本地化的內(nèi)容,例如,它定義了為頁(yè)面指定字符編碼(Encoding)方式的能力。

新的規(guī)范中還加入了一個(gè)TryCatchFinally接口。這個(gè)接口允許標(biāo)記在出現(xiàn)意料不到的異常時(shí)更好地進(jìn)行資源清理工作。

JSP 1.2和Servlet 2.3規(guī)范實(shí)現(xiàn)了兩個(gè)目標(biāo)。它們澄清了當(dāng)前規(guī)范中容易混淆的幾個(gè)問(wèn)題,增加了一些開發(fā)者需要的新功能。主要的變化包括監(jiān)聽器、過(guò)濾器以及經(jīng)過(guò)修改的標(biāo)記庫(kù)模型。新的規(guī)范放在http://java.sun.com/aboutJava/communityprocess/first/jsr053/index.html供任何人閱讀和評(píng)議,你不妨找來(lái)一讀,看看它是否能夠使你的工作更加輕松、簡(jiǎn)單。


標(biāo)簽:servlet2.3(續(xù))