淺談JSP自定義標籤實現過程

本文將通過自定義標籤顯示日期爲例,簡單談談JSP自定義標籤實現過程。包括沒有正文的JSP自定義標籤實現、沒有正文的但帶有屬性的JSP自定義標籤標籤實現等等內容

(一) 沒有正文的JSP自定義標籤實現

(1):定義JSP自定義標籤處理類

  1. import java.io.IOException;  
  2. import java.util.Date;  
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.jsp.JspException;  
  5. import javax.servlet.jsp.JspWriter;  
  6. import javax.servlet.jsp.tagext.Tag;  
  7. import javax.servlet.jsp.tagext.TagSupport;  
  8. //無正文標籤類繼承的是TagSupport類 實現的接口是Tag。 如果有正文的標籤類繼承的是BodyTagSupport類 實現的接口是BodyTag  
  9. public class DateTagNoBody extends TagSupport {  
  10.  @Override  
  11.  public int doStartTag() throws JspException {  
  12.   HttpServletRequest request;  
  13.   // 是TagSupport類中定義的一個屬性,它是javax.servlet.jsp.PageContext的對象  
  14.   request = (HttpServletRequest) pageContext.getRequest();  
  15.   java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat("yyyy-MM-dd");  
  16.   String date = formater.format(new Date());  
  17.   JspWriter out = pageContext.getOut();  
  18.   try {  
  19.    out.print(date);  
  20.   } catch (IOException e) {  
  21.    e.printStackTrace();  
  22.   }  
  23.   // doStartTag() 方法返回 SKIP_BODY 。當然其原因是我們的簡單日期標記沒有正文。  
  24.   return Tag.SKIP_BODY;  
  25.  }  

(2) 定義tld文件

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <taglib> 
  3.    <tlibversion>1.0</tlibversion> 
  4.    <jspversion>1.1</jspversion> 
  5.   <tag> 
  6.     <name>displayDate</name> 
  7.     <tagclass>cn.com.chenlly.tag.DateTagNoBody</tagclass> 
  8.     <bodycontent>empty</bodycontent> 
  9.   </tag>           
  10. </taglib> 

(3) JSP頁面動態引用

  1. <%@ page language="java" pageEncoding="UTF-8"%> 
  2. <%@ taglib uri="/WEB-INF/datetag.tld" prefix="c"%> 
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
  4. <html> 
  5.   <head> 
  6.   </head> 
  7.   <body> 
  8.    <c:displayDate/> 
  9.   </body> 
  10. </html> 

注意:動態引用和靜態引用的區別。

爲了進行靜態引用,首先必須將下面的項加入到web.xml 文件中:

  1. <?xml version="1.0" encoding="ISO-8859-1" ?> 
  2. <Web-app>         
  3.    <taglib> 
  4.       <taglib-uri>myTags</taglib-uri> 
  5.       <taglib-location>/WEB-INF/lib/DateTagLib.tld</taglib-location> 
  6.    </taglib>                 
  7. </Web-app> 

然後,將JSP 聲明加入到所有需要使用自定義標記庫的頁面中:

  1. <%@ taglib uri="myTags" prefix="c" %> 

指定的uri 屬性與在web.xml 文件中指定的taglib-uri 值相匹配。

在進行標記庫的靜態引用時,JSP 聲明必須查詢 web.xml 文件以執行庫查詢。這意味着如果移動或者重命名了庫,或者希望在 web.xml 文件中加入更多的庫,就必須停止服務器、更新 web.xml 文件、然後重新啓動服務器。動態方法讓JSP頁直接指向 TLD 位置,因而是在解釋JSP頁面時進行處理。

(二)  沒有正文的但帶有屬性的JSP自定義標籤標籤實現

(1):定義JSP自定義標籤處理類

  1. import java.io.IOException;  
  2. import java.util.Date;  
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.jsp.JspException;  
  5. import javax.servlet.jsp.JspWriter;  
  6. import javax.servlet.jsp.tagext.Tag;  
  7. import javax.servlet.jsp.tagext.TagSupport;  
  8. //無正文標籤類繼承的是TagSupport類 實現的接口是Tag。 如果有正文的標籤類繼承的是BodyTagSupport類 實現的接口是BodyTag  
  9. public class DateTagNoBody extends TagSupport {  
  10.    
  11.  private String pattern;  
  12.  @Override  
  13.  public int doStartTag() throws JspException {  
  14.   HttpServletRequest request;  
  15.   // 是TagSupport類中定義的一個屬性,它是javax.servlet.jsp.PageContext的對象  
  16.   request = (HttpServletRequest) pageContext.getRequest();  
  17.   java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat(pattern);  
  18.   String date = formater.format(new Date());  
  19.   JspWriter out = pageContext.getOut();  
  20.   try {  
  21.    out.print(date);  
  22.   } catch (IOException e) {  
  23.    e.printStackTrace();  
  24.   }  
  25.   // doStartTag() 方法返回 SKIP_BODY 。當然其原因是我們的簡單日期標記沒有正文。  
  26.   return Tag.SKIP_BODY;  
  27.  }  
  28.    
  29.  //必須實現setXX()方法  
  30.  public void setPattern(String pattern){  
  31.   this.pattern = pattern;  
  32.  }  

(2) 定義tld文件

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <taglib>  
  3.    <tlibversion>1.0</tlibversion>  
  4.    <jspversion>1.1</jspversion>  
  5.   <tag>  
  6.     <name>displayDate</name>  
  7.     <tagclass>cn.com.chenlly.tag.DateTagNoBody</tagclass>  
  8.     <bodycontent>empty</bodycontent>  
  9.     <!-- 定義屬性 -->  
  10.     <attribute>  
  11.        <name>pattern</name> <!-- 屬性名字 -->  
  12.        <type>String</type>  <!-- 屬性類型 -->  
  13.        <requried>false</requried> <!-- 是否必須 -->  
  14.        <rtexprvale>false</rtexprvale> <!-- 表示是否可以使用JSP表達式  -->  
  15.   </attribute>  
  16.   </tag>  
  17. </taglib> 

(3)JSP頁面動態引用

  1. <%@ page language="java" pageEncoding="UTF-8"%> 
  2. <%@ taglib uri="/WEB-INF/datetag.tld" prefix="c"%> 
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
  4. <html> 
  5.   <head> 
  6.   </head> 
  7.   <body> 
  8.    <c:displayDate pattern='yyyy-MM-dd'/> 
  9.    </br> 
  10.    <c:displayDate pattern='MM/dd HH:mm:ss'/> 
  11.   </body> 
  12. </html> 

(三) 有正文的且帶有屬性的JSP自定義標籤實現

(1):定義JSP自定義標籤處理類

  1. import java.io.IOException;  
  2. import java.util.Date;  
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.jsp.JspException;  
  5. import javax.servlet.jsp.JspWriter;  
  6. import javax.servlet.jsp.tagext.BodyContent;  
  7. import javax.servlet.jsp.tagext.BodyTagSupport;  
  8.  
  9. public class BodyTag extends BodyTagSupport {  
  10.    
  11.  private int count;  
  12.  
  13.  private HttpServletRequest reqeust;  
  14.  
  15.  private JspWriter out;  
  16.  
  17.    
  18.  public void init() {  
  19.   reqeust = (HttpServletRequest) pageContext.getRequest();  
  20.   out = pageContext.getOut();  
  21.  }  
  22.  
  23.  @Override  
  24.  public int doStartTag() throws JspException {  
  25.   init();  
  26.   return this.EVAL_BODY_INCLUDE;  
  27.  }  
  28.    
  29.  //設置當前標籤體  
  30.  @Override  
  31.  public void setBodyContent(BodyContent bodyContent) {  
  32.   this.bodyContent = bodyContent;  
  33.   System.out.println("setBodyContent...");   
  34.  }  
  35.    
  36.  
  37. //需要初始化bodyContent  
  38.  @Override  
  39.  public void doInitBody() throws JspException {  
  40.   System.out.println("init.....");  
  41.  }   
  42.  
  43.  
  44.  @Override  
  45.  public int doAfterBody() throws JspException {  
  46.   if (count >= 1) {  
  47.    try {  
  48.     out.println(count);  
  49.     out.println("<Br>");  
  50.    } catch (IOException e) {  
  51.     e.printStackTrace();  
  52.    }  
  53.    count --;  
  54.    return this.EVAL_BODY_AGAIN;  
  55.   } else {  
  56.    return this.SKIP_BODY;  
  57.   }  
  58.  }  
  59.  
  60.  @Override  
  61.  public int doEndTag() throws JspException {  
  62.   java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat(  
  63.     "yyyy-MM-dd");  
  64.   String date = formater.format(new Date());  
  65.   try {  
  66.    out.print(date);  
  67.   } catch (IOException e) {  
  68.    e.printStackTrace();  
  69.   }  
  70.   return this.EVAL_PAGE;  
  71.  }  
  72.  
  73.  // 必須實現setXX()方法  
  74.  public void setCount(int count) {  
  75.   this.count = count;  
  76.  }  

(2) 定義tld文件

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <taglib> 
  3.    <tlibversion>1.0</tlibversion> 
  4.    <jspversion>1.1</jspversion> 
  5.   <tag> 
  6.     <name>iterator</name> 
  7.     <tagclass>cn.com.chenlly.tag.BodyTag</tagclass> 
  8.     <bodycontent>jsp</bodycontent> 
  9.     <!-- 定義屬性 --> 
  10.     <attribute> 
  11.        <name>count</name> <!-- 屬性名字 --> 
  12.        <type>int</type>  <!-- 屬性類型 --> 
  13.        <requried>false</requried> <!-- 是否必須 --> 
  14.        <rtexprvale>false</rtexprvale> <!-- 表示是否可以使用JSP表達式  --> 
  15.   </attribute> 
  16.   </tag> 
  17. </taglib> 

(3) jsp 頁面動態引用

  1. <%@ page language="java" pageEncoding="UTF-8"%> 
  2. <%@ taglib uri="/WEB-INF/bodytag.tld" prefix="c"%> 
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
  4. <html> 
  5.   <head> 
  6.   </head> 
  7.   <body> 
  8.    <c:iterator count="10">HelloWorld!</c:iterator> 
  9.    <%  
  10.     out.println("Bye Bye");  
  11.     %> 
  12.   </body> 
  13. </html> 

效果圖:

執行順序

doStartTag()->setBodyContent()->doInitBody()->doAfterTag()->doEndTag()

如果doStartTag()返回的是EVAL_BODY_INCLUDE執行doAfterTag()方法,

如果它返回SKIP_BODY就執行doEndTag()方法。

setBodyContent()方法用於設置標籤體內容,如果在計算BodyContent時需要進行一些初始化工作,

則在doInitBody()方法中完成。標籤體內容執行完後,會調用doAfterBody()方法

在doAfterTag()方法中返回EVAL_BODY_AGAIN來重複執行doAfterTag()方法

返回SKIP_BODY值則執行doEndTag()方法。

在doEndTag()方法中返回EVAL_PAGE值,則執行此標籤的後的其它代碼,

返回SKIP_PAGE則不執行此頁面的其它代碼。


複製來源:http://developer.51cto.com/art/200907/134263.htm

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