Javaweb實現自定義標簽:將方法封裝到自定義標簽處理類中,然後使用方法與JSTL標簽一致。在實際開發中,前臺頁面是不允許html代碼和java代碼相混合的,但有時jsp或第三方為我們提供的標簽滿足不了需求,這時需要通過自己將業務邏輯封裝到繼承jsp規範的類或介面的處理類中來定義標簽,這就是所謂的 ...
你可以不去造輪子,但是你得知道輪子怎麼造。
Javaweb實現自定義標簽:將方法封裝到自定義標簽處理類中,然後使用方法與JSTL標簽一致。在實際開發中,前臺頁面是不允許html代碼和java代碼相混合的,但有時jsp或第三方為我們提供的標簽滿足不了需求,這時需要通過自己將業務邏輯封裝到繼承jsp規範的類或介面的處理類中來定義標簽,這就是所謂的自定義標簽。這樣的缺點是加重了工作量。但與前端人員溝通和後期的維護上來看,這點工作是微不足道的。
- 創建一個類,如TimeTag,繼承TagSupport類。為自定義標簽添加屬性,需要再java類中創建對應屬性,並實現set方法,在後面的tld註冊是,為tag標簽添加attribute。
- 在WEB-INF下創建一個tld的文件。這是一個標簽庫文件,我們所定義的標簽都要在這個tld文件中進行註冊。這個tld文件可以在tomcat安裝目錄下的webapps\examples\WEB-INF\jsp中找到。
如:
<?xml version="1.0" encoding="ISO-8859-1" ?> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>lzqTag</short-name> <uri>/lzqTag</uri> <description> 這是一個標簽庫 </description> <tag> <name>time</name> <tag-class>com.lzq.tag.TimeTag</tag-class> <body-content>empty</body-content> <!-- body-content標簽有4個值:empty,JSP,scriptless,tagdependent: 1.empty:它是一個空的標簽體。 2.JSP:是允許標簽體內出現JSP腳本,也就是java代碼。 3.scriptless:可以接受文本,EL表達式,和JSP的動作。 4.tagdependent:它是指在標簽體的內容可以直接被寫入bodyContent,由自定義標簽處理類來處理,而不被JSP容器所解析。 --> <description> Perform a server side action; Log the message. </description> <attribute> <name>str</name> <required>true</required> </attribute> </tag> </taglib>
3.在jsp中引入標簽庫,如:<%@ taglib prefix="lzqtag" uri="/lzqTag" %>,併在body中使用<lzqtag:time str=’’ />
Tag介面:
int SKIP_BODY = 0; // 跳過標簽體,不執行標簽體的內容 int EVAL_BODY_INCLUDE = 1; // 執行自定義標簽的標簽體 int SKIP_PAGE = 5; // 告訴web容器忽略標簽後面的內容 int EVAL_PAGE = 6; // 告訴web容器繼續執行標簽後面的代碼 // 在jsp運行過程中,遇見自定義標簽後,執行的方法:返回常量SKIP_BODY、EVAL_BODY_INCLUDE int doStartTag() throws JspException; // 在執行標簽的結束標誌後,執行該方法:返回常量SKIP_PAGE、EVAL_PAGE int doEndTag() throws JspException;
IterationTag介面:
int EVAL_BODY_AGAIN = 2; // // 提供了對標簽內容迴圈的功能:返回EVAL_BODY_AGAIN,一直迴圈,知道返回常量SKIP_BODY、EVAL_BODY_INCLUDE int doAfterBody() throws JspException;
SimpleTag介面:
在源碼中可以看到SimpleTag介面有5個方法,
1、doTag()方法是核心方法,我們可以將所有的標簽處理邏輯都寫在這個方法中,這個方法會拋出一個JspException,然後我們可以通過這個異常通知WEB容器,不再執行此標簽後面的內容。
2、setParent(JspTag),這個方法呢,由WEB容器所調用的,是將父標簽處理器對象傳遞給標簽處理器。
3、getParent()是獲取當前標簽的父標簽對象,比如在標簽嵌套時,可以用此方法得到當前標簽的父標簽。
4、setJSPContext(JspContext)這個方法也是由容器調用的,這個方法是將JSP頁面中的pageContext對象傳遞給標簽處理器對象。
5、setJspBody(JspFragment)這個方法也由web容器調用,意思是將代表當前標簽體的JspFragment對象傳遞給標簽處理器對象,這裡的參數可以理解為標簽體的內容。
註意:JSP引擎在處理簡單標簽的標簽時,會將標簽體中的內容封裝到JspFragment這個參數中,並調用setJspBody(JspFragment)將該對象傳遞給標簽處理器,我們就可以根據需求來控制是否輸出標簽體或者迴圈標簽體。