日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义标签 (转载)

發布時間:2025/7/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义标签 (转载) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://www.cnblogs.com/zhaoyang/archive/2011/12/25/2301108.html?
?

JSP自定義標簽開發入門

JSP自定義標簽開發入門

一般情況下開發jsp自定義標簽需要引用以下兩個包

?

import?javax.servlet.jsp.*;

import?javax.servlet.jsp.tagext.*;

?

首先我們需要大致了解開發自定義標簽所涉及到的接口與類的層次結構(其中SimpleTag接口與SimpleTagSupport類是JSP2.0中新引入的)。

?

目標1:自定義一個用表格顯示用戶信息的簡單標簽

?

效果圖:

在jsp頁面使用此自定義標簽:

?

假設我們有一個UserInfo的javabean,那么在JSP頁面使用此標簽只需調用此標簽即可

?

<!-- 創建需要展現UserInfo的實例(用于測試數據) -->

??? <%

??? UserInfo user =?new?UserInfo();

??? user.setUserName("Xuwei");

??? user.setAge(33);

??? user.setEmail("test@test.test");

??? pageContext.setAttribute("userinfo", user);??

??? %>

?

??? <!-- 給標簽設置user屬性綁定要展現的UserInfo對象? -->

??? <cc:showUserInfo user="${pageScope.userinfo }"?/>

?

開發步驟:

?

簡單標簽的開發我們只要實現Tag接口即可,為了簡單起見可以直接繼承實現了此接口的TagSupport類

?

1 創建自定義標簽類

?

public?class?UserInfoTag?extends?TagSupport {

???

????private?UserInfo user;

?

??? @Override

????public?int?doStartTag()?throws?JspException {

????????try?{

??????????? JspWriter out =?this.pageContext.getOut();

????????????if(user ==?null) {

??????????????? out.println("No UserInfo Found...");

????????????????return?SKIP_BODY;

??????????? }

??????????? out.println("<table width='500px' border='1' align='center'>");

??????????? out.println("<tr>");

??????????? out.println("<td width='20%'>Username:</td>");

??????????? out.println("<td>" + user.getUserName() + "</td>");

??????????? out.println("</tr>");

??????????? out.println("<tr>");

??????????? out.println("<td>Age:</td>");

??????????? out.println("<td>" + user.getAge() + "</td>");

??????????? out.println("</tr>");

??????????? out.println("<tr>");

??????????? out.println("<td>Email:</td>");

??????????? out.println("<td>" + user.getEmail() + "</td>");

??????????? out.println("</tr>");

??????????? out.println("</table>");

??????? }?catch(Exception e) {

????????????throw?new?JspException(e.getMessage());

??????? }

????????return?SKIP_BODY;

??? }

???

??? @Override

????public?int?doEndTag()?throws?JspException {

????????return?EVAL_PAGE;

??? }

?

??? @Override

????public?void?release() {

????????super.release();

????????this.user =?null;

??? }

???

??? //getter and setters

????public?UserInfo getUser() {

????????return?user;

??? }

????public?void?setUser(UserInfo user) {

????????this.user = user;

??? }

}

?

2 在Web-Inf創建標簽庫描述文件.tdl(Tag Library Description)

?

<?xml version="1.0"?encoding="UTF-8"?>

<taglib version="2.0"?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">

<tlib-version>1.0</tlib-version>

<jsp-version>2.0</jsp-version>

<short-name>cc</short-name>

<uri>/mytaglib</uri>

<tag>

??? <name>showUserInfo</name>

??? <tag-class>com.mytags.UserInfoTag</tag-class>

??? <body-content>empty</body-content>

??? <attribute>

??????? <name>user</name>

?? ????? <required>false</required>

?? ????? <rtexprvalue>true</rtexprvalue>

??? </attribute>

?</tag>

</taglib>

?

3 配置web.xml

?

<jsp-config>

? ? <taglib>

? ????? <taglib-uri>/mytaglib</taglib-uri>

? ????? <taglib-location>/WEB-INF/mytaglib.tld</taglib-location>

? ? </taglib>

? </jsp-config>

?

4 在需要使用此標簽的jsp頁面頭部引入

?

<%@ taglib uri="/mytaglib" prefix="cc"%>

?

5 使用(參照上面的使用步驟)

?

此致,一個簡單的JSP標簽開發完成

?

標簽類說明:

我們創建的UserInfoTag類繼承了TagSupport類,而它又實現了Tag接口,Tag接口的生命周期由其所在的容器控制,如下圖:

?

setPageContext() 將所在jsp頁面的pageContext注入進來,目的是為了在后面的方法中可以訪問到jsp頁面對象的pageContext屬性

?

setParent()?????? 設置此標簽的父標簽

?

setAttribute()?? 將標簽中的屬性注入到此class的屬性,不需要自己實現但要提供屬性的get與set方法

?

doStartTag()????? 在開始標簽屬性設置后調用,如果返回SKIP_BODY則忽略標簽之中的內容,如果返回EVAL_BODY_INCLUDE則將標簽體的內容進行輸出

?

doEndTag()???????? 在結束標簽之前調用,返回SKIP_PAGE跳過整個jsp頁面后面的輸出,返回EVAL_PAGE執行頁面余下部分

?

release()????????? 生命周期結束時調用

?

特別說明:在tomcat4.1之后的版本中默認開啟了標簽緩沖池(websphere和weblogic并不會這么做),所以執行完標簽后并不會執行release()方法(_jspDestroy()時才釋放),也就是說同一個jsp頁面自定義標簽不管使用多少次只會存在一個實例,但也并不是每一個標簽都會為其創建一個緩沖池,要根據參數來判斷,例如:

<cc:UserInfoTag user=”…” />

<cc:UserInfoTag />

上面例子中由于參數不同就會創建兩個標簽緩沖池。

?

這個問題可以通過設定tomcat的配置文件加以解決:
在%tomcat%\conf\web.xml加入enablePooling參數,并設置為false(不緩存自定義標簽)。

<init-param>
? <param-name>enablePooling</param-name>
? <param-value>false</param-value>
</init-param>
?

清空%tomcat%\conf\目錄

-------------------------------------------------------------------------------------------------------------------------------

TagSupport類已經為我們實現并擴展了一些方法(比如在上述方法中我們可以直接使用pageContext對象,調用父標簽getParent()等),所以一般情況下我們只需重寫doStartTag(),doEndTag() 即可

?

TLD文件說明:

<!--版本號-->

<tlib-version>1.0</tlib-version>

<jsp-version>2.0</jsp-version>

<short-name>cc</short-name>

<tag>

<!—指定標簽名 -->

??? <name>showUserInfo</name>

<!—指定標簽類文件的全路徑 -->

??? <tag-class>com.mytags.UserInfoTag</tag-class>

<!--如果不需要標簽體則設置empty,反之設定jsp -->

??? <body-content>empty</body-content>

<!—設定屬性(如果有的話) -->

??? <attribute>

<!—指定標簽名 -->

?????? <name>user</name>

<!—是否是必須,如果非必須沒設置則為空 -->

?? ???? <required>false</required>

<rtexprvalue>true</rtexprvalue><!—是否可在屬性中使用表達式 -->

??? </attribute>

</tag>

?

?

Web.xml文件說明:

<jsp-config>

? ? <taglib>

<!--

標簽庫的uri路徑

即jsp頭文件中聲明<%@ taglib uri="/mytaglib" prefix="cc"%>

的uri

?-->

? ????? <taglib-uri>/mytaglib</taglib-uri>

<!—tld文件所在的位置-->

? ????? <taglib-location>/WEB-INF/mytaglib.tld</taglib-location>

? ? </taglib>

? </jsp-config>

?

?

目標2:自定義一個類似于Asp.Net中的Reapter控件的標簽

效果圖:

?

在jsp頁面使用此自定義標簽:

?

<!-- 創建需要展現javabean(UserInfo)集合的實例(用于測試數據) -->

<%

??? List<UserInfo> users =?new?ArrayList<UserInfo>();???

??? users.add(new?UserInfo("Zhangsan", 12, "Zhangsan@163.com"));

??? users.add(new?UserInfo("Lisi", 22, "Lisi@sina.com"));

??? users.add(new?UserInfo("Wangwu", 33, "Wangwu@qq.com"));

??? pageContext.setAttribute("users", users);

%>

?

<!-- 給標簽綁定數據源? -->

<table width='500px'?border='1'?align='center'>

??? <tr>

??? ??? <td width='20%'>UserName</td>

??? ??? <td width='20%'>Age</td>

??? ??? <td>Email</td>

??? </tr>

??? <cc:repeater var="item"?items="${pageScope.users }">

??? ??? <tr>

??? ??? ??? <td>${item.userName }</td>

??? ??? ??? <td>${item.age }</td>

??? ??? ??? <td>${item.email }</td>

??? ??? </tr>

??? </cc:repeater>

</table>

?

開發步驟:

?

要完成此控件我們需要實現一個迭代接口,即IterationTag,由于TagSupport同樣實現了此接口,所以我們繼承此類

?

1 創建自定義標簽類

?

public?class?Repeater?extends?TagSupport {

????private?Collection?items;

????private?Iterator?it;

????private?String var;

?

??? @Override

????public?int?doStartTag()?throws?JspException {

????????if(items ==?null?|| items.size() == 0)?return?SKIP_BODY;

??????? it = items.iterator();??

??????? if(it.hasNext()) {

??????????? pageContext.setAttribute(var, it.next());

??????? }

????????return?EVAL_BODY_INCLUDE;

??? }

???

??? @Override

????public?int?doAfterBody()?throws?JspException {

????????if(it.hasNext()) {

??????????? pageContext.setAttribute(var, it.next());

????????????return?EVAL_BODY_AGAIN;

??????? }

????????return?SKIP_BODY;

??? }

???

??? @Override

????public?int?doEndTag()?throws?JspException {

????????return?EVAL_PAGE;

??? }

???

????public?void?setItems(Collection?items) {

????????this.items = items;

??? }

???

????public?void?setVar(String var) {

????????this.var = var;

??? }

}

?

2在Web-Inf創建標簽庫描述文件.tdl(Tag Library Description)

由于目標1種已經創建了此文件,我們只需增加此標簽的配置即可

?

<tag>

??? <name>repeater</name>

??? <tag-class>com.mytags.Repeater</tag-class>

??? <body-content>jsp</body-content>

??? <attribute>

??????? <name>items</name>

??????? <required>false</required>

??????? <rtexprvalue>true</rtexprvalue>

??? </attribute>

??? <attribute>

??????? <name>var</name>

??????? <required>true</required>

??????? <rtexprvalue>true</rtexprvalue>

??? </attribute>

?</tag>

?

3 配置web.xml (目標1中已完成,無需修改)

?

4 在需要使用此標簽的jsp頁面頭部引入

<%@ taglib uri="/mytaglib" prefix="cc"%>

?

5 使用(參照上面的使用步驟)

?

標簽類說明:

我們用到了迭代接口,以下是容器處理此接口的流程

?

?

作為目標1中的補充: 在doAfterBody()如果返回值是EVAL_BODY_AGAIN那么將重新執行此方法

?

目標3:使用BodyTagSupport

此目標并不會使用實際例子進行顯示,主要是說明為什么,什么情況下需要使用到BodyTag接口或者BodyTagSupport類?

如果我們需要在<test>? ….?? </test>之間的標簽體的頭部和尾部加上一些標記或者是其他處理,一般的處理方法是在doStartTag和doEndTag方法中進行, 但是如果是個迭代標簽,標簽體的每段內容在循環輸出時每次都需要在頭部和尾部加上一些標記,我們使用BodyTagSupport就很方便了,

?

此接口在doStartTag()方法返回值多了一個EVAL_BODY_BUFFERED,它將對主體進行計算,并輸出到緩沖區(注:此處是緩沖區并非直接輸出到客戶端,需要我們手動(this.bodyContent.getEnclosingWriter().write(this.bodyContent.getString());)進行輸出客戶端的調用,否則主體內容不會進行顯示)

?

標簽類說明:

關于BodyTagSupport接口的說明

?

目標4:自定義的函數庫

1 創建函數庫類

?

public?class?MyFunctions {

????public?static?String formatMyName(String name) {

???????return?"your name is " + name;

??? }

????public?static?int?add(int?a,?int?b) {

???????return?a+b;

??? }

}

?

2 在TLD文件中配置 (引用于目標1中的tld文件)

<function>

??? <name>formatMyName</name>

??? <function-class>com.taglib.MyFunctions</function-class>

??? <function-signature>java.lang.String formatMyName(java.lang.String)</function-signature>

?</function>

?

<function>

??? <name>add</name>

??? <function-class>com.taglib.MyFunctions</function-class>

??? <function-signature>java.lang.String add(int,?int)</function-signature>

?</function>

?

3 JSP中調用

?

${cc:formatMyName("wangfei") }

${cc:add(12, 34) }

轉載于:https://www.cnblogs.com/heling/archive/2012/08/03/2622187.html

總結

以上是生活随笔為你收集整理的自定义标签 (转载)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。