jsp的自定義標籤

堅持每天寫博文,積累下開發中的點點滴滴 

繼承TagSupport:

首先創建一個普通java類MyTagText繼承TagSupport,該類爲某一標籤定義操作。

重寫父類的setPageContext方法,用於得到當前jsp頁面的pageContext對象。

重寫父類的doStartTag方法,定義標籤具體操作

public class MyTagText extends TagSupport{
	
	private PageContext pageContext;


	//重寫父類的setPageContext方法,用於得到當前jsp頁面的pageContext對象。
	@Override
	public void setPageContext(PageContext pageContext) {
		this.pageContext = pageContext;
	}
	//重寫父類的doStartTag方法,裏面寫上你定義的標籤的java操作
	//這裏我定義的標籤用作向瀏覽器輸出一大段信息:
	@Override
	public int doStartTag() throws JspException {
		try {
			pageContext.getResponse().getWriter().write("AAAAAAAAA");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.doStartTag();
	}
	//這樣就完成一個標籤處理程序了.寫完程序我們還需要註冊它。
}
我們需要在tld文件中註冊


在你的web應用目錄下,找到WEB-INF文件夾,在裏面新建一個tld類型的文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
  <taglib>
  	<tlib-version>1.0</tlib-version><!-- 代表標籤庫的版本號 -->
  	 <jsp-version>1.2</jsp-version><!-- 代表jsp的版本 -->
  	 <short-name>mtt</short-name><!-- 你的標籤庫的簡稱 -->
  	 <uri>http://vmaxtam.com/mytag</uri><!-- 你標籤庫的引用uri -->
  	 
  	  <tag>
  	  	<name>mytab</name><!-- 你定義的標籤的名稱 -->
  	  	<tag-class>CustomTag.MyTagText</tag-class><!-- 對應的標籤處理程序:包名+類名 -->
  	  	<body-content>JSP</body-content><!-- 標籤體內容的格式 -->
  	  </tag>
  </taglib>
現在可以在JSP中使用了記得導入標籤:
<%@taglib uri="http://vmaxtam.com/mytag" prefix="mmt" %>

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://vmaxtam.com/mytag" prefix="mmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mmt:mytab></mmt:mytab>
</body>
</html>
效果如下:




參考:https://www.cnblogs.com/vmax-tam/p/4145334.html   作者:白Rime


自定義標籤的原理

1)當服務器打開時,就會加載WEB-INF下的資源文件,包括web.xml 和 tld文件,把它們加載到內存

2)我們在瀏覽器輸入http://localhost:8080/TestArea/testit.jsp來訪問jsp頁面

3)服務器讀取testit.jsp裏的內容,當讀到

<%@taglib uri="http://vmaxtam.com/mytag" prefix="mmt" %> 

這一句的時候,就會在內存中找是否存在urihttp://vmaxtam.com/mytagtld文件,找不到就會報錯

4)繼續讀取jsp頁面,讀到<mmt:mytag>這個標籤的時候,就會通過uri找到tld文件,在tld文件中找到mytab是否被定義,是的話就得到它的tag-class的內容,然後去找到它對應的標籤處理程序

5)實例化標籤處理程序,利用生成的對象調用它裏面的方法

這裏服務器對標籤處理程序裏的方法也有一定的調用順序      A)void setPageContext(PageContext pc)  --傳入pageContext對象

B)void setParent(Tag t)              --如果有父標籤,傳入父標籤對象,如果沒有,則傳入null

C)int doStartTag()                 --開始執行標籤時調用。

D)int doEndTag()                --結束標籤時調用

E)void release()                  --釋放資源

 

如果你沒有重寫上面的方法,系統將會調用它的父類裏的方法~


爲什麼會是這個順序調用,是有證據的,下面我們來看看jsp被翻譯爲java源文件裏的截取:

 

複製代碼
private boolean _jspx_meth_itcast_005fshowIp_005f0(PageContext _jspx_page_context)
          throws Throwable {
    PageContext pageContext = _jspx_page_context;
    JspWriter out = _jspx_page_context.getOut();
    //  itcast:showIp
   1) 實例化ShowIpTag對象
    gz.itcast.tag.ShowIpTag _jspx_th_itcast_005fshowIp_005f0 = (gz.itcast.tag.ShowIpTag) _005fjspx_005ftagPool_005fitcast_005fshowIp_005fnobody.get(gz.itcast.tag.ShowIpTag.class);
    2)調用setPageContext方法
 _jspx_th_itcast_005fshowIp_005f0.setPageContext(_jspx_page_context);
    3)調用setParent方法
    _jspx_th_itcast_005fshowIp_005f0.setParent(null);
  4)調用doStartTag方法
    int _jspx_eval_itcast_005fshowIp_005f0 = _jspx_th_itcast_005fshowIp_005f0.doStartTag();
   5)調用doEndTag方法
    if (_jspx_th_itcast_005fshowIp_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
      _005fjspx_005ftagPool_005fitcast_005fshowIp_005fnobody.reuse(_jspx_th_itcast_005fshowIp_005f0);
      return true;
    }
    _005fjspx_005ftagPool_005fitcast_005fshowIp_005fnobody.reuse(_jspx_th_itcast_005fshowIp_005f0);
    return false;
  }
複製代碼

控制標籤體內容 與 結束標籤後的內容



自定義標籤可以可控制標籤體內的文本 和 結束標籤後的文本是否輸出~

 

複製代碼
    @Override//遇到開始標籤時執行的方法
    public int doStartTag() throws JspException {
        
        //return Tag.SKIP_BODY; //標籤體內容不向瀏覽器輸出
        return Tag.EVAL_BODY_INCLUDE;//標籤體內容向瀏覽器輸出
    }    
    @Override//遇到結束標籤後執行的方法
    public int doEndTag() throws JspException {
    
        //return Tag.EVAL_PAGE;//結束標籤後的內容輸出到瀏覽器
        return Tag.SKIP_PAGE;//結束標籤後的內容不輸出到瀏覽器        
    }
複製代碼

那麼如何重複輸出標籤體內的文本內容呢?TagSupper還提供了一個doAftetBody方法,我們只需要這樣做:

 

複製代碼
    int i = 4;
    @Override//每輸出一次標籤體的內容都會調用一次這個方法
    public int doAfterBody() throws JspException {
        while(true)
        {
            if(i>0)
            {
                i--;
                return IterationTag.EVAL_BODY_AGAIN;//再執行一次便籤體內的內容
            }else{
                break;
            }        
        }
        return Tag.SKIP_BODY;//不輸出標籤體的內容
    }
複製代碼

很可惜,用TagSupport是不行,但是我們可以用它的子類BodyTagSupport,那麼久寫一個類繼承BodyTagSupport類吧~

 

複製代碼
public class MyTagTest extends BodyTagSupport {

    private PageContext pageContext;

    @Override
    public void setPageContext(PageContext pageContext) {
        this.pageContext = pageContext;
    }
    
    @Override
    public int doStartTag() throws JspException {
        
        //返回BodyTag.EVAL_BODY_BUFFERED,表示輸出標籤體內容
        //返回Tag.SKIP_BODY,表示不輸出內容
        return BodyTag.EVAL_BODY_BUFFERED;
        //return Tag.SKIP_BODY;
    }
    
    @Override
    public int doEndTag() throws JspException {
        
        //得到BodyContent對象,它包裝了標籤體裏的內容
        BodyContent bodyContent = this.getBodyContent();
        
        //利用getString方法得到字符串
        String content = bodyContent.getString();
        
        //改變字符串內容,將小寫改爲大寫
        String change = content.toUpperCase();
        
        //輸出到瀏覽器
        try {
            this.pageContext.getResponse().getWriter().write(change);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return Tag.SKIP_PAGE;
    }
}
複製代碼

 

以上~就是自定義標籤的創建步驟會原理,還有一些標籤體內容的處理方法,大家覺得容易嗎?

對,十分的不容易啊,用這種方法定義的標籤我們稱爲傳統標籤,所以這是一個社會問題,是時候就會有人站出來,寫出一組代碼來解決這個問題了,這組代碼稱爲:簡單標籤

 

簡單標籤

https://www.cnblogs.com/fjdingsd/p/5118166.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章