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 }
运行结果: