1. 說(shuō)明
本文檔是學(xué)習(xí)tomcat中例子的筆記,并沒有參考相應(yīng)的說(shuō)明文檔,因此不能保證本文觀點(diǎn)的正確性。如果有不對(duì)之處,不妨email至8280338@tzenet.com,大家共同進(jìn)步。
2. JSP2.0標(biāo)簽使用方法
JSP2.0中標(biāo)簽的使用由多個(gè)部分組成:
(1) WEB_INF/web.xml中添加標(biāo)簽引用
(2) 標(biāo)簽的實(shí)現(xiàn),可能是class也可能是web templet
(3) 在jsp文件中添加引用
在實(shí)際使用中,分析jsp2.0標(biāo)簽可以先從jsp文件入手,然后再分析web.xml及相應(yīng)的標(biāo)簽庫(kù)文件。
2.2 基本標(biāo)簽的使用方法
2.2.1 jsp文件中的標(biāo)簽引用及使用方法
以下是一個(gè)簡(jiǎn)單的jsp文件:
<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
<html> <body> <mytag:helloWorld/> </body></html>
說(shuō)明:
(1) 首先以<%@ taglib prefix="mytag" uri="…" %>說(shuō)明標(biāo)簽前綴及該前綴引用的標(biāo)簽所在路徑,在這個(gè)例子中uri值是一個(gè)相對(duì)路徑(本地路徑),即當(dāng)前項(xiàng)目根目錄下WEB-INF/ jsp2/ jsp2-example-taglib.tld。如果使用的是本地路徑就不需要在web.xml中配置路徑映射了;
(2) 指定了標(biāo)簽前綴后,在jsp頁(yè)面的body內(nèi)就可以使用這個(gè)前綴來(lái)引用標(biāo)簽庫(kù)中的指定標(biāo)簽了,如<mytag:helloWorld/>,就是引用mytag所指定的標(biāo)簽庫(kù)中的helloWorld標(biāo)簽。
2.2.2 web.xml中的配置
如果在上述例子中使用的不是本地路徑,那么就需要在web.xml中配置路徑轉(zhuǎn)換,如使用:<%@ taglib prefix="mytag" uri=" http://mytaglib/myTestTags1 " %>來(lái)引用標(biāo)簽庫(kù),那么就需要在web.xml文件的jsp-config節(jié)點(diǎn)中添加如下配置:
<taglib>
<taglib-uri>http://mytaglib/myTestTags1</taglib-uri>
<taglib-location>/WEB-INF/jsp2/jsp2-example-taglib.tld </taglib-location>
</taglib>
JSP解釋器會(huì)將http://mytaglib/myTestTags1根據(jù)web.xml中的配置轉(zhuǎn)化為本地路徑。當(dāng)然<taglib-uri>中文本可以是任何值,但不能和其它的配置沖突,所以在規(guī)劃時(shí)最好加上前綴,如:http://mytaglib等。
2.2.3 標(biāo)簽庫(kù)中的配置
在標(biāo)簽庫(kù)中的配置實(shí)際上就是配置對(duì)實(shí)現(xiàn)類的引用,JSP解釋器會(huì)根據(jù)jsp文件中對(duì)標(biāo)簽的引用,在標(biāo)簽庫(kù)中找到相應(yīng)的標(biāo)簽,然后再根據(jù)標(biāo)簽中的定義調(diào)用具體的實(shí)現(xiàn)類,本例中在jsp文件中對(duì)標(biāo)簽的引用:<mytag:helloWorld/>,即引用了helloWorld這個(gè)標(biāo)簽,這個(gè)標(biāo)簽在標(biāo)簽庫(kù)中的定義如下:
<tag>
<description>Outputs Hello, World</description>
<name>helloWorld</name>
<tag-class>jsp2.examples.simpletag.HelloWorldSimpleTag</tag-class>
<body-content>empty</body-content>
</tag>
該標(biāo)簽由四個(gè)部分組成:
(1) description:描述該標(biāo)簽的作用
(2) name:標(biāo)簽的名字,該名字在jsp文件使用,相當(dāng)由類名;
(3) tag-class:標(biāo)簽的實(shí)現(xiàn)索引,相當(dāng)于類的實(shí)現(xiàn);本例索引指定jsp2.examples.simpletag.HelloWorldSimpleTag,是一個(gè)java的類文件,應(yīng)放在WEB_INF/classes/jsp2/examples/simpletag目錄下的HelloWorldSimpleTag.class文件;
(4) body-content:在jsp文件中使用標(biāo)簽時(shí),標(biāo)簽中的內(nèi)容類別,本例的值是empty,表示helloWorld這個(gè)標(biāo)簽中沒有內(nèi)容。如果在jsp頁(yè)面中在該標(biāo)簽中加入了內(nèi)容,如<mytag:helloWorld>hell</mytag:helloWorld>,頁(yè)面會(huì)報(bào)錯(cuò),當(dāng)然<mytag:helloWorld></mytag:helloWorld>是不會(huì)錯(cuò)的(注意不能有空格式)。
2.2.4 類的實(shí)現(xiàn)
類HelloWorldSimpleTag實(shí)現(xiàn)如下:
package jsp2.examples.simpletag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
public class HelloWorldSimpleTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
getJspContext().getOut().write( "Hello, world!" );
}}
說(shuō)明:
(1) jsp標(biāo)簽調(diào)用的類一般繼承于SimpleTagSupport
(2) SimpleTagSupport中實(shí)現(xiàn)了getJspContext()這個(gè)方法,這個(gè)方法可以獲取指向jsp頁(yè)面的輸出流。
(3) getJspContext().getOut().write( "Hello, world!" ):輸出Hellow,World!
2.3含有變量的tag配置
2.3.1 jsp文件中的標(biāo)簽引用及使用方法
以下是引用了帶有變量標(biāo)簽的jsp頁(yè)面:
<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/my_taglib.tld" %>
<html><body>
<mytag:repeat num1="15">
Invocation ${count} of 5<br>
</mytag:repeat>
</body>
</html>
說(shuō)明:
(1) <mytag:repeat num="15">,輸入?yún)?shù)的傳入方法:即在標(biāo)簽中將要傳入的參數(shù)做為標(biāo)簽的一個(gè)屬性,并指定其屬性值,本例中傳入?yún)?shù)num1,它的值為15;
(2) ${count},在頁(yè)面中顯示輸出參數(shù)的值,count是輸出參數(shù)的名字
2.3.2 標(biāo)簽庫(kù)中的配置
標(biāo)簽庫(kù)中的相應(yīng)配置如下:
<tag>
<description>Repeats the body of the tag 'num' times</description>
<name>repeat</name>
<tag-class>jsp2.examples.simpletag.RepeatSimpleTag</tag-class>
<body-content>scriptless</body-content>--標(biāo)簽內(nèi)容是腳本
<variable>
<description>Current invocation count (1 to num)</description>
<name-given>count</name-given> --輸出參數(shù)說(shuō)明
</variable>
<attribute>
<name>num</name> --輸入?yún)?shù)說(shuō)明
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
該標(biāo)簽由六個(gè)部分組成:
(1) description:見上文
(2) name:見上文
(3) tag-class:見上文
(4) body-content:這個(gè)例子的值是scriptless,表示標(biāo)簽中的內(nèi)容是腳本
(5) variable:輸出參數(shù),在jsp中使用${count}來(lái)引用這個(gè)輸出變量的值,輸出參數(shù)名并不是強(qiáng)制性的,這里只是一個(gè)約定,即要求repeat實(shí)現(xiàn)類最后有count這個(gè)輸出參數(shù),以便在jsp頁(yè)中方便引用,如果沒有也不會(huì)報(bào)錯(cuò);
(6) attribute:輸入?yún)?shù),在jsp中使用< mytag:repeat num="5">來(lái)設(shè)置這個(gè)輸入?yún)?shù)num,這個(gè)參數(shù)名是強(qiáng)制性的,即要在repeat實(shí)現(xiàn)類中有setNum這個(gè)方法,如果沒有相應(yīng)的方法jsp頁(yè)面會(huì)報(bào)錯(cuò);
2.3.3 類的實(shí)現(xiàn)
package jsp2.examples.simpletag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.util.HashMap;
import java.io.IOException;
public class RepeatSimpleTag1 extends SimpleTagSupport {
private int num;
public void doTag() throws JspException, IOException {
for (int i=0; i<num; i++) {
getJspContext().setAttribute("count", String.valueOf( i + 1 ) );
getJspBody().invoke(null);
} }
public void setNum(int num) {
this.num = num; }}
說(shuō)明:
(1) getJspContext().setAttribute定義了輸出到jsp頁(yè)面的輸出參數(shù)count,這里的count是一個(gè)字符串,它的值可以不與標(biāo)簽庫(kù)中variable定義相同,如,它可以是len,當(dāng)然在jsp引用時(shí)應(yīng)以這里為準(zhǔn),即使用${len}引用;
(2) setNum(int num)方法:接收輸入?yún)?shù),這個(gè)方法命名規(guī)則為set+輸入?yún)?shù)名,該方法帶一個(gè)參數(shù),用于接收輸入?yún)?shù)的值。
2.4 函數(shù)標(biāo)簽的定義方法
2.4.1 jsp文件中函數(shù)標(biāo)簽引用及使用方法
<%@ taglib prefix="my" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
<html>
<body><span>${my:caps(“HELLO WORLD”)}</span></body>
</html>
說(shuō)明:
(1) 函數(shù)標(biāo)簽的引用比其它標(biāo)簽的引用都要簡(jiǎn)單,它的引用與高級(jí)語(yǔ)言中的函數(shù)調(diào)用方法類似,直接在函數(shù)名后的括號(hào)后面輸入相應(yīng)的參數(shù)值即可,不需要另加用標(biāo)簽的其它屬性來(lái)說(shuō)明輸入?yún)?shù)。
2.4.2 函數(shù)標(biāo)簽在標(biāo)簽庫(kù)中配置
<function>
<description>Converts the string to all caps</description>
<name>caps</name>
<function-class>jsp2.examples.el.Functions</function-class>
<function-signature>java.lang.String caps( java.lang.String )</function-signature>
</function>
說(shuō)明如下:
(1) 這種方法的定義包含在function元素中;
(2) name:函數(shù)名
(3) function-class:該函數(shù)真正的實(shí)現(xiàn)class,本例中,caps函數(shù)是由WEB_INF/classes/ jsp2/examples/el路徑中的Functions類來(lái)實(shí)現(xiàn)的;
(4) function-signature:說(shuō)明函數(shù)的輸入及輸出參數(shù)類型,不用指明參數(shù)名。
2.4.3 類的實(shí)現(xiàn)
package jsp2.examples.el;
import java.util.*;
public class Functions {
public static String caps( String text ) {
return text.toUpperCase();
}}
說(shuō)明:
(1) 函數(shù)標(biāo)簽實(shí)現(xiàn)類就是普通的類,它不需要從某個(gè)父類繼承;
(2) 函數(shù)標(biāo)簽實(shí)現(xiàn)類中必須有相應(yīng)的方法與標(biāo)簽庫(kù)中相應(yīng)的函數(shù)字義相同(包括函數(shù)名,輸入?yún)?shù)個(gè)數(shù)及輸入?yún)?shù)類型,函數(shù)的返回值);
2.5 標(biāo)簽?zāi)0?/SPAN>
標(biāo)簽?zāi)0宓奶攸c(diǎn):
(1) 沒有tld文件在jsp中通過(guò)<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>引用,即使用tagdir代替了uri,這里的tags是一個(gè)文件夾,不是文件,在該文件夾中包含了所需的標(biāo)簽?zāi)0澹?/SPAN>
(2) 通過(guò)以下方式傳入?yún)?shù)值:
<tags:displayProducts>
<jsp:attribute name="normalPrice">....</jsp:attribute>
<jsp:attribute name="onSale">....</jsp:attribute>
.....
</tags:displayProducts>
(3) displayProducts是與/WEB-INF/tags目錄中的某個(gè)文件名;
(4) 通過(guò)<jsp:attribute name="…. ">來(lái)賦值
(5) 標(biāo)簽?zāi)0迨且粋€(gè)純文本文件,類似于html文件,而不需要通過(guò)java的類來(lái)實(shí)現(xiàn)標(biāo)簽的定義;
(6) 個(gè)人認(rèn)為標(biāo)簽?zāi)0宓闹饕饔弥卦谂虐妫渌鼧?biāo)簽的作用重在功能的實(shí)現(xiàn);本人不打算在以后的開發(fā)使用標(biāo)簽?zāi)0澹虼吮疚牟辉龠M(jìn)一步分析標(biāo)簽?zāi)0濉?/SPAN>
3. 參考
http://localhost:8080/jsp-examples/