JSP規範_Tag Library標簽庫
- 什麽是標簽庫
標簽庫是jsp頁面要使用的標簽元素的集合,前面筆記總結的都是默認的標簽,容器提供了另外幾套標準標簽庫和用戶自定以標簽庫來零化jsp頁面中java代碼,我將不筆記標準標簽 庫的各個細則,只約略記錄一下sun公司提供的幾個標簽有:c/fmc/sql/x/fn幾個前綴標識,它封裝了程序員常用的一些標簽,我個人是不提倡用這些標簽因為難以記憶,如果有公司 采用這樣的技術手段,只需要查規範即可,標簽本質上只是java代碼的標簽化而已。然後如果有公司使用自定義標簽庫,則只需要知道標簽庫如何自定義和使用即可。下面的內容 將圍繞自定義標簽展開。
一個標簽的組成
標簽概念的完全組成部分是空標簽、標簽屬性和標簽體。自定義的標簽實際上就是實現了傳統標簽和簡單標簽接口的java類,然後完成標簽類的部署工作後,程序員就可以在jsp中 使用。
- 標簽接口在容器中的生命周期:
javax.servlet.jsp.tagext.Tag接口作為頂級接口定義了標簽需要實現的基本方法,其相關類的靜態層次這裏忽視,只約略筆記相關的幾個周期方法:
1.1容器在創建標簽處理器的實例後(需要部署告知容器),調用setPageContext()方法設置標簽的頁面上下文,然後調用setParent()設置此標簽的父標簽,沒有則為null;
1.2調用標簽處理器的setXXX(),設置標簽的屬性,如果jsp中的標簽定義屬性則沒有這一步驟;
1.3調用doStartTag()方法,如果返回EVAL_BODY_INCLUDE常量(接口中定義的),則將標簽體輸出到當前的輸出流中;如果返回SKIP_BODY則忽略標簽體。
1.4調用doEndTag()方法,返回PAGE,則執行jsp頁面之余,返回SKIP_BODY則忽略頁面之余;和上一步驟類似,該步驟中的代碼會原樣編寫進jsp對應的servlet代碼中。
1.5容器緩存該實例,重復使用;
1.6需要釋放該實例時,調用release();
知道了其生命周期後,我們就可以實現簡單標簽或傳統標簽接口,在對應的方法中寫入合適的處理內容。
2.標簽實現類的部署
完成標簽處理器的編寫後,需要告知容器該處理器的信息,讓容器擁有對處理器的管理權。
2.1標簽庫描述符(Tag Library Descriptor,TLD)
編寫.tld文件到META-INF或WEB-INF目錄下(最好創建自目錄tags),下面貼上一個案例:
代碼結構:
編寫便簽處理器HelloTag.java
package tags; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.Tag; //實現傳統標簽接口 public class HelloTag implements Tag{ private PageContext pageContext; private Tag parent; //設置context對象 public void setPageContext(PageContext pc) { this.pageContext=pc; } //如果標簽嵌套,設置父標簽 public void setParent(Tag t) { this.parent=t; } //獲取父標簽 public Tag getParent() { return parent; } //當處理標簽時,該方法被調用 public int doStartTag() throws JspException { return SKIP_BODY;//有效返回值0,跳過body評估,即忽略標簽體 } //當處理結束時,該方法被調用 public int doEndTag() throws JspException { JspWriter out = pageContext.getOut(); try { out.println("歡迎來到我的個人網站!"); }catch(IOException e) { System.out.println(e.toString()); } return EVAL_PAGE;//返回6,繼續評估該page,即jsp頁面的余下部分繼續執行 } @Override public void release() {}//釋放標簽處理器資源 }View Code
標簽描述文件MyTaglib.tld
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.1"> <tlib-version>1.0</tlib-version> <short-name>my</short-name><!-- 為標簽庫定義一個簡短名字,jsp頁面編輯使用 ,作為首先前綴值使用--> <display-name>My Tag</display-name><!-- 為標簽庫指定一個簡短名字,被一些工具所顯示 --> <discription>Custom Tag library</discription> <tag><!-- 沒有屬性沒有標簽體的標簽 --> <name>hello</name> <tag-class>tags.HelloTag</tag-class> <body-content>empty</body-content> </tag> <tag><!-- 帶屬性 的標簽 --> <name>max</name> <tag-class>tags.MaxTag</tag-class> <body-content>empty</body-content> <attribute> <name>num1</name> <required>true</required><!-- 設置標簽屬性為必填 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>num2</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag><!-- 帶標簽體的標簽 --> <name>greet</name> <tag-class>tags.GreetTag</tag-class> <body-content>JSP</body-content><!-- 代表標簽體可以包含jsp代碼 --> </tag> <!-- <description/> 為標簽庫提供一個文本描述 <smaill-icon/> 為標簽庫提供小圖標 <large-icon/> 為標簽庫提供大圖標 <validator> 標簽庫的驗證器 <description></description> 為驗證器提供一個文本描述 <validator-class></validator-class> 指定驗證的實現類 <init-param></init-param> 驗證類的初始化參數 </validator> <listener> 標簽庫的監聽器 <description/> 監聽器提供一個文本描述 <dispalay-name/> 簡短名字 <icon> 指定圖標 <small-icon/> 指定小圖標 <large-scon/> 大圖標 </icon> <listener-class/> 指定監聽器類完全限定名 </listener> <tag>指定標簽的配置信息 <description/> 為標簽庫提供一個文本描述 <display-name></display-name> 為標簽指定一個簡短名字 <icon> <small-icon/><large-icon/> </icon> <name></name> 指定自定義標簽的名字 <tag-class/> 指定標簽的實現類 <tei-class/> 為容器在轉換階段提供該標簽的附加信息 <body-content/> 指定標簽體的格式 </tag> <tag-file> 關於該標簽文件的信息 <description/> 標簽文件提供一個文本描述 <display-name/> 為標簽文件提供一個簡短名 <icon/> 為標簽文件指定大小圖標,省略子標簽 <name/> 指定標簽文件的名字 <path/> 指定標簽文件的路徑 <example/> 提供一個使用例子描述 <tag-extension/> 提供標簽的擴展信息 </tag-file> <function> 與EL表達式有關 <description/> 為EL函數指定一個簡短名字 <icon/> 指定一個圖標 ,子標簽省略 <name/> 給函數指定一個名字 <function-class/> 實現el函數的類完全限定 <function-signture/> 指定EL函數的原型 <example/> 提供一個使用案例 <function-extension/> 提供額外信息 </function> --> </taglib>View Code
可以看到,文件中每一個tag標簽就是對一個實現Tag接口的處理器的描述,標簽的name屬性,作為jsp中指示要使用的標簽的標識,jap中使用標簽庫+標簽名的方式來定位要使 用的標簽。標簽庫會在web.xml中進行說明。
標簽庫在容器中的部署web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <!-- 標簽即動作!! --> <!-- 對自定義標簽的部署,即容器啟動時就根據部署文件找到tld,再根據tld找到對應的標簽實現類,再jsp的解析過程中遇到標簽就替換成對應的實現類代碼 --> <jsp-config><!-- 為jsp提供全局配置信息 --> <taglib><!-- 為頁面的tag提供部署 --> <taglib-uri>/mytag</taglib-uri><!-- 對應jsp中的uri標識 --> <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location> </taglib> </jsp-config> </web-app>View Code
該文件中主要告知容器標簽庫的描述文件,讓容器啟動時根據描述文件加載標簽處理器。
自定義標簽的使用hello.jsp
<%@ page language="java" contentType="text/html; charset=gb2312"%> <%@ taglib uri="/mytag" prefix="my" %><!-- 指定標簽庫及其簡短表示,根據uri去部署描述文件中尋找對應的標簽描述文件即可找到對應的標簽類 --> <html> <head> <title><my:hello/></title><!-- 說明使用標簽庫中的某個標簽 --> </head> <body> <my:hello/> </body> </html>View Code
總結:盡管個人不是很提供使用標簽,但是不排除有技術成熟的公司在使用,如果項目中遇到,則以上的案例作為基本的操作指南:在jsp中使用taglib指令說明要使用的標簽所在的標簽庫,即web.xml中對應標簽庫描述文件的uri標識;找到標簽文件所在位置打開,查找標簽庫的short name作為jsp中taglib指令的prefix,即可在使用某個標簽時使用前綴+標簽名的方式定位要使用的標簽;在標簽文件中找到要使用的tag標簽name,就可以標簽庫前綴+標簽名使用了。標準標簽庫可以理解為sun公司給寫好的自定義標簽,文章開始已經談到就不再贅述,如果要使用就可以直接再jsp中使用taglib指令和前綴+標簽的方式使用即可。EL表達式可以理解為對javabean的直接訪問,也不作為重點學習目標,因為他們本質上只是簡化jsp中的java代碼而已,如果用到可以查閱規範!
JSP規範_Tag Library標簽庫