一:自定标签前需要了解的知识:
BodyTagSupport类的方法:
编写标签对应的实现类时,需要重载BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag();
他们执行顺序如下:
doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()
doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,
如果返回EVAL_BODY_INCLUDE则继续执行;
如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,
而直接执行doEndTag()方法。
setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。
标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY,
EVAL_PAGE或SKIP_PAGE。
如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;
如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;
如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。
标签中静态常量:
EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流
SKIP_BODY:告诉服务器不要处理正文内容
EVAL_PAGE:让服务器继续执行页面
SKIP_PAGE:让服务器不要处理剩余的页面
EVAL_BODY_AGAIN:让服务器继续处理正文内容,只有doAfterBody方法可以返回
EVAL_BODY_BUFFERED:BodyTag接口的字段,在doStartTag()返回
EVAL_BODY_INCLUDE、SKIP_BODY一般由doStartTag()返回,而EVAL_PAPGE、SKIP_PAGE由doEndTag()返回。
二:自定义标签调用的SeclectAllSt.java类,SeclectStBySex.java类继承TagSupport类
1 package com.bjsxt.sxf.tag; 2 3 import java.io.IOException; 4 import java.util.List; 5 6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.JspWriter; 8 import javax.servlet.jsp.tagext.TagSupport; 9 10 import org.apache.struts2.ServletActionContext; 11 import org.springframework.context.ApplicationContext; 12 import org.springframework.web.context.support.WebApplicationContextUtils; 13 14 import com.bjsxt.sxf.dao.StudentDao; 15 import com.bjsxt.sxf.po.Student; 16 /** 17 * 简单的自定义Struts2标签,没有属性的 18 * @ClassName: SeclectAllSt 19 * @Description: TODO(这里用一句话描述这个类的作用) 20 * @author 尚晓飞 21 * @date 2014-10-21 下午3:21:16 22 * 23 */ 24 public class SeclectAllSt extends TagSupport { 25 private static final long serialVersionUID = 1L; 26 27 //空构造 28 public SeclectAllSt(){ 29 System.out.println("SeclectAllSt.SeclectAllSt(构造函数)"); 30 } 31 32 //标签执行顺序 doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag() 33 //标签开始访问 34 @Override 35 public int doStartTag() throws JspException { 36 // TODO Auto-generated method stub 37 System.out.println("SeclectAllSt.doStartTag(开始运行标签函数)"); 38 return SKIP_BODY;//则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,而直接执行doEndTag()方法 39 } 40 41 //标签结束访问 42 @Override 43 public int doEndTag() throws JspException { 44 // TODO Auto-generated method stub 45 System.out.println("SeclectAllSt.doEndTag(标签结束运行函数)"); 46 //查询出所有学生的信息 47 //获取ioc容器(ssh中spring) 48 ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); 49 //获取与数据库交互的dao 50 StudentDao dao=(StudentDao) app.getBean("StudentDao"); 51 //查询出所有的学生信息 52 List<Student> students=dao.queryAll(); 53 //通过父类TagSupport的属性值pageContext 取得相关的内置对象 54 //=============pageContext还可以get更多的内置对象。 55 // pageContext.getRequest(); 56 // pageContext.getResponse(); 57 // pageContext.getSession(); 58 // pageContext.getServletContext(); 59 JspWriter out=pageContext.getOut(); 60 //遍历循环打印 61 62 try { 63 out.print("<table border=\"1\">"); 64 out.print("<tr>"); 65 out.print("<td>id</td>"); 66 out.print("<td>姓名</td>"); 67 out.print("<td>性别</td>"); 68 out.print("<td>班级</td>"); 69 out.print("</tr>"); 70 for(int i=0;i<students.size();i++){ 71 Student student=students.get(i); 72 out.print("<tr>"); 73 out.print("<td>"+student.getId()+"</td>"); 74 out.print("<td>"+student.getName()+"</td>"); 75 out.print("<td>"+student.getSex()+"</td>"); 76 out.print("<td>"+student.getClassRoom().getName()+"</td>"); 77 out.print("</tr>"); 78 } 79 80 out.print("</table>"); 81 } catch (IOException e) { 82 // TODO Auto-generated catch block 83 e.printStackTrace(); 84 } 85 86 return EVAL_PAGE; 87 } 88 89 90 91 92 93 94 } 95 96 97 98 package com.bjsxt.sxf.tag; 99 100 import java.io.IOException; 101 import java.util.List; 102 103 import javax.servlet.jsp.JspException; 104 import javax.servlet.jsp.JspWriter; 105 import javax.servlet.jsp.tagext.TagSupport; 106 107 import org.apache.struts2.ServletActionContext; 108 import org.springframework.context.ApplicationContext; 109 import org.springframework.web.context.support.WebApplicationContextUtils; 110 111 import com.bjsxt.sxf.dao.StudentDao; 112 import com.bjsxt.sxf.po.Student; 113 /** 114 * 有属性的标签(根据性别) 115 * @ClassName: SeclectStBySex 116 * @Description: TODO(这里用一句话描述这个类的作用) 117 * @author 尚晓飞 118 * @date 2014-10-21 下午3:56:48 119 * 120 */ 121 public class SeclectStBySex extends TagSupport{ 122 private static final long serialVersionUID = 1L; 123 private String sex;//标签属性传递的值,会通过set get方法 124 125 //标签开始执行的方法 126 @Override 127 public int doStartTag() throws JspException { 128 System.out.println("SeclectStBySex.doEndTag(标签开始)"); 129 return SKIP_BODY; 130 } 131 132 //最后执行的方法 133 @Override 134 public int doEndTag() throws JspException { 135 // TODO Auto-generated method stub 136 System.out.println("SeclectAllSt.doEndTag(标签结束运行函数)"); 137 //查询出所有学生的信息 138 //获取ioc容器(ssh中spring) 139 ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); 140 //获取与数据库交互的dao 141 StudentDao dao=(StudentDao) app.getBean("StudentDao"); 142 //查询出指定性别的学生集合 143 List<Student> students=dao.queryBySex(sex); 144 //通过父类TagSupport的属性值pageContext 取得相关的内置对象 145 //=============pageContext还可以get更多的内置对象。 146 // pageContext.getRequest(); 147 // pageContext.getResponse(); 148 // pageContext.getSession(); 149 // pageContext.getServletContext(); 150 JspWriter out=pageContext.getOut(); 151 //遍历循环打印 152 153 try { 154 out.print("<table border=\"1\">"); 155 out.print("<tr>"); 156 out.print("<td>id</td>"); 157 out.print("<td>姓名</td>"); 158 out.print("<td>性别</td>"); 159 out.print("<td>班级</td>"); 160 out.print("</tr>"); 161 for(int i=0;i<students.size();i++){ 162 Student student=students.get(i); 163 out.print("<tr>"); 164 out.print("<td>"+student.getId()+"</td>"); 165 out.print("<td>"+student.getName()+"</td>"); 166 out.print("<td>"+student.getSex()+"</td>"); 167 out.print("<td>"+student.getClassRoom().getName()+"</td>"); 168 out.print("</tr>"); 169 } 170 171 out.print("</table>"); 172 } catch (IOException e) { 173 // TODO Auto-generated catch block 174 e.printStackTrace(); 175 } 176 return EVAL_PAGE; 177 } 178 179 180 public String getSex() { 181 return sex; 182 } 183 184 public void setSex(String sex) { 185 this.sex = sex; 186 } 187 188 189 }
三:在项目webroot/web-inf/下建立自定义标签库的.tld文件 str.tld
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> 3 <taglib> <!-- 自定义库标签的根 --> 4 <tlibversion>1.2</tlibversion> <!-- 版本号 --> 5 <jspversion>1.1</jspversion> <!-- JSP版本号 --> 6 <shortname>stu</shortname> <!-- prefix="stu"标签名称--> 7 <uri>StudentTags</uri> <!-- uri="StudentTags" 外界导入标签时,认识的名字,很重要。--> 8 9 <tag> 10 <name>selectAll</name> <!-- 标签名称 --> 11 <tagclass>com.bjsxt.sxf.tag.SeclectAllSt</tagclass> <!-- 对应的java类的全路径 --> 12 </tag> 13 14 <!-- 有属性的标签,可以有多个属性 <attribute>并列 --> 15 <tag> 16 <name>selectBySex</name> <!-- 标签名称 --> 17 <tagclass>com.bjsxt.sxf.tag.SeclectStBySex</tagclass> 18 <attribute> <!-- 对应标签的属性。 --> 19 <name>sex</name> 20 <required>true</required> <!-- 是必需写的属性,即没有写属性标签不能被正常使用 --> 21 </attribute> 22 </tag> 23 24 </taglib>
四:页面上测试jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib uri="StudentTags" prefix="stu" %> 3 <% 4 String path = request.getContextPath(); 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 6 %> 7 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 9 <html> 10 <head> 11 </head> 12 13 <body> 14 This is my JSP page. <br> 15 <a href="<%=request.getContextPath()%>/StudentAction!reportStudent.action">班级表单下载</a> 16 <!-- 查询出所有学生 --> 17 <stu:selectAll></stu:selectAll> 18 <!-- 查询出指定性别的学生 --> 19 <stu:selectBySex sex="男"></stu:selectBySex> 20 </body> 21 22 </html>
五:效果图