web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 5 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 6 7 <jsp-config> 8 <taglib> 9 <taglib-uri>/WEB-INF</taglib-uri> 10 <taglib-location>/WEB-INF/mytag.tld</taglib-location> 11 </taglib> 12 </jsp-config> 13 </web-app>
mytag.tld
1 <?xml version="1.0" encoding="UTF-8"?> 2 <taglib> 3 <tlibversion>1.0</tlibversion> 4 <jspversion>1.1</jspversion> 5 6 <tag> 7 <name>displayDate</name> 8 <tagclass>gys.DateTagNoBody</tagclass> 9 <bodycontent>empty</bodycontent> <!-- 標簽體之間的內容要為空 --> 10 </tag> 11 <tag> 12 <name>displayDateTwo</name> 13 <tagclass>gys.DateTagAttribute</tagclass> 14 <bodycontent>empty</bodycontent> <!-- 標簽體之間的內容要為空 --> 15 <!-- 定義屬性 --> 16 <attribute> 17 <name>pattern</name> <!-- 屬性名字 --> 18 <type>String</type> <!-- 屬性類型 --> 19 <requried>false</requried> <!-- 是否必須 --> 20 <rtexprvale>false</rtexprvale> <!-- 表示是否可以使用JSP表達式 --> 21 </attribute> 22 </tag> 23 24 <tag> 25 <name>iterator</name> 26 <tagclass>gys.BodyTag</tagclass> 27 <bodycontent>jsp</bodycontent> 28 <!-- 定義屬性 --> 29 <attribute> 30 <name>count</name> <!-- 屬性名字 --> 31 <type>int</type> <!-- 屬性類型 --> 32 <requried>false</requried> <!-- 是否必須 --> 33 <rtexprvale>false</rtexprvale> <!-- 表示是否可以使用JSP表達式 --> 34 </attribute> 35 </tag> 36 37 </taglib>
BodyTag.java
1 package gys; 2 3 import java.io.IOException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.jsp.JspException; 9 import javax.servlet.jsp.JspWriter; 10 import javax.servlet.jsp.tagext.BodyContent; 11 import javax.servlet.jsp.tagext.BodyTagSupport; 12 13 public class BodyTag extends BodyTagSupport { 14 15 // 執行順序 16 // 17 // doStartTag()->setBodyContent()->doInitBody()->doAfterTag()->doEndTag() 18 // 19 // 如果doStartTag()返回的是EVAL_BODY_INCLUDE執行doAfterTag()方法, 20 // 21 // 如果它返回SKIP_BODY就執行doEndTag()方法。 22 // 23 // setBodyContent()方法用於設置標簽體內容,如果在計算BodyContent時需要進行一些初始化工作, 24 // 25 // 則在doInitBody()方法中完成。標簽體內容執行完后,會調用doAfterBody()方法 26 // 27 // 在doAfterTag()方法中返回EVAL_BODY_AGAIN來重復執行doAfterTag()方法 28 // 29 // 返回SKIP_BODY值則執行doEndTag()方法。 30 // 31 // 在doEndTag()方法中返回EVAL_PAGE值,則執行此標簽的后的其它代碼, 32 // 33 // 返回SKIP_PAGE則不執行此頁面的其它代碼。 34 35 private int count; 36 37 private HttpServletRequest reqeust; 38 39 private JspWriter out; 40 41 public void init() { 42 reqeust = (HttpServletRequest) pageContext.getRequest(); 43 out = pageContext.getOut(); 44 } 45 46 @Override 47 public int doStartTag() throws JspException { 48 init(); 49 return this.EVAL_BODY_INCLUDE;//執行doAterTag()方法 50 } 51 52 // 設置當前標簽體 53 @Override 54 public void setBodyContent(BodyContent bodyContent) { 55 this.bodyContent = bodyContent; 56 //System.out.println("setBodyContent..."); 57 } 58 59 // 需要初始化bodyContent 60 @Override 61 public void doInitBody() throws JspException { 62 System.out.println("init....."); 63 } 64 65 @Override 66 public int doAfterBody() throws JspException { 67 if (count >= 1) { 68 try { 69 out.println(count); 70 out.println("<Br>"); 71 } catch (IOException e) { 72 e.printStackTrace(); 73 } 74 count--; 75 return this.EVAL_BODY_AGAIN;//在doAfterBody中返回,會重復執行doAfterBody方法 76 } else { 77 return this.SKIP_BODY;//執行doEndTag 78 } 79 } 80 81 @Override 82 public int doEndTag() throws JspException { 83 SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); 84 String date = formater.format(new Date()); 85 try { 86 out.print(date); 87 } catch (IOException e) { 88 e.printStackTrace(); 89 } 90 return this.EVAL_PAGE;//不執行此頁面的其它代碼 91 } 92 93 // 必須實現setXX()方法 94 public void setCount(int count) { 95 System.out.println("count........"); 96 this.count = count; 97 } 98 }
DateTagAttributr.java
1 package gys; 2 3 import java.io.IOException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.jsp.JspException; 9 import javax.servlet.jsp.JspWriter; 10 import javax.servlet.jsp.tagext.Tag; 11 import javax.servlet.jsp.tagext.TagSupport; 12 13 public class DateTagAttribute extends TagSupport { 14 15 private String pattern; 16 17 @Override 18 public int doStartTag() throws JspException { 19 HttpServletRequest request; 20 // 是TagSupport類中定義的一個屬性,它是javax.servlet.jsp.PageContext的對象 21 request = (HttpServletRequest) pageContext.getRequest(); 22 SimpleDateFormat formater = new SimpleDateFormat(pattern); 23 String date = formater.format(new Date()); 24 JspWriter out = pageContext.getOut(); 25 try { 26 out.print(date); 27 } catch (IOException e) { 28 e.printStackTrace(); 29 } 30 // doStartTag() 方法返回 SKIP_BODY 。當然其原因是我們的簡單日期標記沒有正文。 31 return Tag.SKIP_BODY; 32 } 33 34 // 必須實現setXX()方法 35 public void setPattern(String pattern) { 36 this.pattern = pattern; 37 } 38 }
DateTagNoBody.java
1 package gys; 2 3 import java.io.IOException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.jsp.JspException; 9 import javax.servlet.jsp.JspWriter; 10 import javax.servlet.jsp.tagext.Tag; 11 import javax.servlet.jsp.tagext.TagSupport; 12 13 public class DateTagNoBody extends TagSupport { 14 15 @Override 16 public int doStartTag() throws JspException { 17 HttpServletRequest request=(HttpServletRequest)pageContext.getRequest(); 18 SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd"); 19 String date=formater.format(new Date()); 20 JspWriter out=pageContext.getOut(); 21 try{ 22 out.print(date); 23 } 24 catch(IOException e){ 25 e.printStackTrace(); 26 } 27 return Tag.SKIP_BODY; 28 } 29 30 }
運行結果: