第一建立一个java类:
public class HelloWorldTag extends SimpleTagSupport { //重写doTag方法,该方法在标签结束生成页面内容 public void doTag()throws JspException, IOException { //获取页面输出流,并输出字符串 getJspContext().getOut().write("Hello World " + new java.util.Date()); } }
2.建立TLD(Tag Library Definition)文件:
<?xml version="1.0" encoding="GBK"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>mytaglib</short-name> <!-- 定义该标签库的URI --> <uri>/mytaglib</uri> <!-- 定义第一个标签 --> <tag> <!-- 定义标签名 --> <name>helloWorld</name> <!-- 定义标签处理类 --> <tag-class>lee.HelloWorldTag</tag-class> <!-- 定义标签体为空 --> <body-content>empty</body-content> </tag> </taglib>
标签库的使用:
第一:前提条件:
1.标签库URI:确定使用那个标签库。
2标签名:确定使用那个标签。
步骤:
1导入标签库
<%@ taglib uri="tagliburi" prefix="tagPrefix"%>
2在jsp页面中使用标签
<tagPrefix:tagName tagAttribute="tagValue" ...> <tagBody/> </tagPrefix:tagName>
实例:根据上文建立的tld,编写如下jsp页面
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!-- 导入标签库,指定mytag前缀的标签,由http://www.crazyit.org/mytaglib的标签库处理 --> <%@ taglib uri="/mytaglib" prefix="mytag"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>自定义标签示范</title> <meta name="website" content="http://www.crazyit.org" /> </head> <body bgcolor="#ffffc0"> <h2>下面显示的是自定义标签中的内容</h2> <!-- 使用标签 ,其中mytag是标签前缀,根据taglib的编译指令,
mytag前缀将由http://www.crazyit.org/mytaglib的标签库处理 --> <mytag:helloWorld/><br/> </body> </html>
还要加上一步:
在web.xml文件中添加引入代码:
<jsp-config> <taglib> <taglib-uri>/mytaglib</taglib-uri> <taglib-location>/WEB-INF/mytaglib.tld</taglib-location> </taglib> </jsp-config>
<!-- 定义第二个标签 --> <tag> <!-- 定义标签名 --> <name>query</name> <!-- 定义标签处理类 --> <tag-class>lee.QueryTag</tag-class> <!-- 定义标签体为空 --> <body-content>empty</body-content> <!-- 配置标签属性:driver --> <attribute> <name>driver</name> <required>true</required> <fragment>true</fragment> </attribute> <!-- 配置标签属性:url --> <attribute> <name>url</name> <required>true</required> <fragment>true</fragment> </attribute> <!-- 配置标签属性:user --> <attribute> <name>user</name> <required>true</required> <fragment>true</fragment> </attribute> <!-- 配置标签属性:pass --> <attribute> <name>pass</name> <required>true</required> <fragment>true</fragment> </attribute> <!-- 配置标签属性:sql --> <attribute> <name>sql</name> <required>true</required> <fragment>true</fragment> </attribute> </tag>
java代码清单:
public class QueryTag extends SimpleTagSupport { //标签的属性
private String driver; private String url; private String user; private String pass; private String sql; //setter和getter方法省略 //执行数据库访问的对象 private Connection conn = null; private Statement stmt = null; private ResultSet rs = null; private ResultSetMetaData rsmd = null; public void doTag()throws JspException, IOException { try { //注册驱动 Class.forName(driver); //获取数据库连接 conn = DriverManager.getConnection(url,user,pass); //创建Statement对象 stmt = conn.createStatement(); //执行查询 rs = stmt.executeQuery(sql); rsmd = rs.getMetaData(); //获取列数目 int columnCount = rsmd.getColumnCount(); //获取页面输出流 Writer out = getJspContext().getOut(); //在页面输出表格 out.write("<table border='1' bgColor='#9999cc' width='400'>"); //遍历结果集 while (rs.next()) { out.write("<tr>"); //逐列输出查询到的数据 for (int i = 1 ; i <= columnCount ; i++ ) { out.write("<td>"); out.write(rs.getString(i)); out.write("</td>"); } out.write("</tr>"); } } catch(ClassNotFoundException cnfe) { cnfe.printStackTrace(); throw new JspException("自定义标签错误" + cnfe.getMessage()); } catch (SQLException ex) { ex.printStackTrace(); throw new JspException("自定义标签错误" + ex.getMessage()); } finally { //关闭结果集 try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException sqle) { sqle.printStackTrace(); } } } }
tld内容:
<!-- 定义第三个标签 --> <tag> <!-- 定义标签名 --> <name>iterator</name> <!-- 定义标签处理类 --> <tag-class>lee.IteratorTag</tag-class> <!-- 定义标签体不允许出现JSP脚本 --> <body-content>scriptless</body-content> <!-- 配置标签属性:collection --> <attribute> <name>collection</name> <required>true</required> <fragment>true</fragment> </attribute> <!-- 配置标签属性:item --> <attribute> <name>item</name> <required>true</required> <fragment>true</fragment> </attribute> </tag>
package org.sh.com.tag; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; import java.util.*; public class IteratorTag extends SimpleTagSupport { // 标签属性,用于指定需要被迭代的集合 private String collection; // 标签属性,指定迭代集合元素,为集合元素指定的名称 private String item; // collection属性的setter和getter方法 public void setCollection(String collection) { this.collection = collection; } public String getCollection() { return this.collection; } // item属性的setter和getter方法 public void setItem(String item) { this.item = item; } public String getItem() { return this.item; } // 标签的处理方法,简单标签处理类只需要重写doTag方法 public void doTag() throws JspException, IOException { // 从page scope中获取属性名为collection的集合 Collection itemList = (Collection) getJspContext().getAttribute( collection); // 遍历集合 for (Object s : itemList) { // 将集合的元素设置到page 范围 getJspContext().setAttribute(item, s); // 输出标签体 getJspBody().invoke(null); } } }
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <%@ page import="java.util.*"%> <!-- 导入标签库,指定mytag前缀的标签, 由http://www.crazyit.org/mytaglib的标签库处理 --> <%@ taglib uri="/mytaglib" prefix="mytag"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> 带标签体的标签-迭代器标签 </title> <meta name="website" content="http://www.crazyit.org" /> </head> <body> <h2>带标签体的标签-迭代器标签</h2><hr/> <% //创建一个List对象 List<String> a = new ArrayList<String>(); a.add("疯狂Java"); a.add("www.crazyit.org"); a.add("java"); //将List对象放入page范围内 pageContext.setAttribute("a" , a); %> <table border="1" bgcolor="#aaaadd" width="300"> <!-- 使用迭代器标签,对a集合进行迭代 --> <mytag:iterator collection="a" item="item"> <tr> <td>${pageScope.item}</td> <tr> </mytag:iterator> </table> </body> </html>
tld文件:
<tag> <!-- 定义标签名 --> <name>fragment</name> <!-- 定义标签处理类 --> <tag-class>lee.FragmentTag</tag-class> <!-- 指定该标签不支持标签体 --> <body-content>scriptless</body-content> <!-- 定义标签属性:fragment --> <attribute> <name>fragment</name> <required>true</required> <fragment>true</fragment> </attribute> </tag>
java文件:
public class FragmentTag extends SimpleTagSupport { private JspFragment fragment; //fragment属性的setter和getter方法 public void setFragment(JspFragment fragment) { this.fragment = fragment; } public JspFragment getFragment() { return this.fragment; } @Override public void doTag() throws JspException, IOException { JspWriter out = getJspContext().getOut(); out.println("<div style='padding:10px;border:1px solid black'>"); out.println("<h3>下面是动态传入的JSP片段</h3>"); //调用、输出“页面片段” fragment.invoke( null ); out.println("</div"); } }
jsp文件:
<%@ page contentType="text/html; charset=GBK" language="java" errorPage=""%> <!-- 导入标签库,指定mytag前缀的标签, 由http://www.crazyit.org/mytaglib的标签库处理 --> <%@ taglib uri="/mytaglib" prefix="mytag"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>自定义标签示范</title> <meta name="website" content="http://www.crazyit.org" /> </head> <body bgcolor="#ffffc0"> <h2>下面显示的是自定义标签中的内容</h2> <mytag:fragment> <jsp:attribute name="fragment"> <mytag:helloWorld /> </jsp:attribute> </mytag:fragment> <br /> <mytag:fragment> <jsp:attribute name="fragment"> ${pageContext.request.remoteAddr} </jsp:attribute> </mytag:fragment> </body> </html>
把<mytag:fragment> 开始标签
与</mytag:fragment>结束标签之间的注释全部去掉——HTML注释、JSP注释都要去掉。
——最新版本的Tomcat不允许此处出现注释
动态属性的标签比普通标签多了如下两个额外的要求:
-->标签处理累还需要实现DynamivAttributes接口。
-->配置标签是通过<dynamic-attributes…/>子元素制定该标签支持动态属性
下面一个例子:
java代码:
public class DynaAttributesTag extends SimpleTagSupport implements DynamicAttributes { // 保存每个属性名的集合 private ArrayList<String> keys = new ArrayList<String>(); // 保存每个属性值的集合 private ArrayList<Object> values = new ArrayList<Object>(); @Override public void doTag() throws JspException, IOException { JspWriter out = getJspContext().getOut(); // 此处只是简单地输出每个属性 out.println("<ol>"); for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); Object value = values.get(i); out.println("<li>" + key + " = " + value + "</li>"); } out.println("</ol>"); } @Override public void setDynamicAttribute(String uri, String localName, Object value) throws JspException { // 添加属性名 keys.add(localName); // 添加属性值 values.add(value); } }
TLD代码:
<!-- 定义接受动态属性的标签 --> <tag> <name>dynaAttr</name> <tag-class>org.sh.com.tag.DynaAttributesTag</tag-class> <body-content>empty</body-content> <!-- 指定支持动态属性 --> <dynamic-attributes>true</dynamic-attributes> </tag>
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!-- 导入标签库,指定mytag前缀的标签, 由http://www.crazyit.org/mytaglib的标签库处理 --> <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>自定义标签示范</title> <meta name="website" content="http://www.crazyit.org" /> </head> <body bgcolor="#ffffc0"> <h2>下面显示的是自定义标签中的内容</h2> <h4>指定两个属性</h4> <mytag:dynaAttr name="crazyit" url="crazyit.org"/><br/> <h4>指定四个属性</h4> <mytag:dynaAttr 书名="疯狂Java讲义" 价格="99.0" 出版时间="2008年" 描述="Java图书"/><br/> </body> </html>
另注:body-content取值的意义 转自:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8157212
body-content的值有下面4种:
<xsd:enumeration value="tagdependent"/> <xsd:enumeration value="JSP"/> <xsd:enumeration value="empty"/> <xsd:enumeration value="scriptless"/>
tagdependent:标签体内容直接被写入BodyContent,由自定义标签类来进行处理,而不被JSP容器解释,
如下:
<test:myList> select name,age from users </test:myList>
JSP:接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。如:
<my:test> <%=request.getProtocol()%> // ② </my:test>
具体可参考后面附源码。
empty:空标记,即起始标记和结束标记之间没有内容。
下面几种写法都是有效的,
<test:mytag /> <test:mytag uname="Tom" /> <test:mytag></test:mytag>
scriptless:接受文本、EL和JSP动作。如上述②使用<body-content> scriptless </body-content>则报错,具体可参考后面附源码。