您的位置:首页 > Web前端 > JavaScript

jsp的自定义标签

2016-03-14 15:29 387 查看
http://blog.csdn.net/u010819416/article/details/43318029

一种可在页面中使用的标签,这种标具有和HTML标签类似的语法,但又可以完成JSP脚本的功能——这种标签就是JSP自定义标签。

开发标签库的步骤:

1、开发自定义标签处理类;

2、建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库可包含多个标签;

3、在jsp文件中使用自定义标签。


2.11.1 开发自定义标签类

*自定义标签类应该继承一个父类:java.servlet.jsp.tagext.SimpleTagSupport;

*如果标签类包含属性,每个属性都有对应的getter和setter方法;

*重写doTag()方法,这个方法负责生产页面内容

例子:

在页面上输出HelloWord的标签:HelloWorldTag.java

[java] view
plain copy

print?

package lee;

import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.io.*;

public class HelloWorldTag extends SimpleTagSupport

{

//重写doTag方法,该方法在标签结束生成页面内容

public void doTag()throws JspException,

IOException

{

//获取页面输出流,并输出字符串

getJspContext().getOut().write("Hello World "

+ new java.util.Date());

}

}

2.11.2建立TLD文件

TLD(Tag Library Definition),标签库定义。标签库定义文件的根元素是taglib,它可以包含多个tag子元素,每个tag子元素都定义一个标签。

例子:mytaglib.tld

[html] view
plain copy

print?

<?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>http://www.crazyit.org/mytaglib</uri>

<!-- 定义第一个标签 -->

<tag>

<!-- 定义标签名 -->

<name>helloWorld</name>

<!-- 定义标签处理类 -->

<tag-class>lee.HelloWorldTag</tag-class>

<!-- 定义标签体为空 -->

<body-content>empty</body-content>

</tag>

</taglib>

标签库文件放在Web应用的WEB-INF路径或任意子路径下,Java Web规范会自动加载该文件,则该文件定义的标签库也将生效。

2.11.3 使用标签库

1、导入标签库:使用taglib编译指令导入标签库,就是将标签库和指定前缀关联起来。

2、使用标签:在JSP页面中使用自定义标签。

taglib的语法格式如下:

<%@ taglib uri="tagliburi" prefix="tagPrefix"%>

其中uri属性指定标签库的URI,这个URI可以确定一个标签库。而prefix属性指定标签库前缀,即所有使用该前缀的标签将由此标签库处理。

使用标签的语法格式如下:

<tagPrefix:tagName tagAttribute="tagValue" ...>

<tagBody/>

</tagPrefix:tagName>

如果该标签没有标签体,则可以使用如下语法格式:

<tagPrefix:tagName tagAttribute="tagValue" .../>

例子:helloWorldTag.jsp

[java] view
plain copy

print?

<%@ 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>

<!-- 使用标签 ,其中mytag是标签前缀,根据taglib的编译指令,

mytag前缀将由http://www.crazyit.org/mytaglib的标签库处理 -->

<mytag:helloWorld/><br/>

</body>

</html>

2.11.4 带属性的标签

例子:QueryTag.java

[java] view
plain copy

print?

package lee;

import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.io.*;

import java.sql.*;

[java] view
plain copy

print?

public class QueryTag extends SimpleTagSupport

{

//标签的属性

private String driver;

private String url;

private String user;

private String pass;

private String sql;

//driver属性的setter和getter方法

public void setDriver(String driver)

{

this.driver = driver;

}

public String getDriver()

{

return this.driver;

}

//url属性的setter和getter方法

public void setUrl(String url)

{

this.url = url;

}

public String getUrl()

{

return this.url;

}

//user属性的setter和getter方法

public void setUser(String user)

{

this.user = user;

}

public String getUser()

{

return this.user;

}

//pass属性的setter和getter方法

public void setPass(String pass)

{

this.pass = pass;

}

public String getPass()

{

return this.pass;

}

//sql属性的setter和getter方法

public void setSql(String sql)

{

this.sql = sql;

}

public String getSql()

{

return this.sql;

}

//conn属性的setter和getter方法

public void setConn(Connection conn)

{

this.conn = conn;

}

public Connection getConn()

{

return this.conn;

}

//stmt属性的setter和getter方法

public void setStmt(Statement stmt)

{

this.stmt = stmt;

}

public Statement getStmt()

{

return this.stmt;

}

//rs属性的setter和getter方法

public void setRs(ResultSet rs)

{

this.rs = rs;

}

public ResultSet getRs()

{

return this.rs;

}

//rsmd属性的setter和getter方法

public void setRsmd(ResultSetMetaData rsmd)

{

this.rsmd = rsmd;

}

public ResultSetMetaData getRsmd()

{

return this.rsmd;

}

//执行数据库访问的对象

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();

}

}

}

}

对于有属性的标签,需要为<tag.../>元素增加<attribute.../>子元素,每个attribute子元素定义一个标签属性。<attribute.../>子元素通常还需要指定如下几个子元素:

1、name:设置属性名,子元素的值是字符串内容

2、required:设置该属性是否为必须属性

3、fragment: 设置该属性是否支持JSP脚本、表达式等动态内容

[html] view
plain copy

print?

<!-- 定义第二个标签 -->

<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>

使用标签:queryTag.jsp

[java] view
plain copy

print?

<%@ 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>

<!-- 使用标签 ,其中mytag是标签前缀,根据taglib的编译指令,

mytag前缀将由http://www.crazyit.org/mytaglib的标签库处理 -->

<mytag:query

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/javaee"

user="root"

pass="32147"

sql="select * from news_inf"/><br/>

</body>

</html>

*JSTL是sun提供的一套标签库,这套标签库的功能非常强大(就是C标签)。


2.11.5 带标签体的标签

带标签体的标签,可以在标签内嵌入其他内容(包括静态的HTML内容和动态的JSP内容),通常用于完成一些逻辑运算,例如判断和循环等。

迭代器标签例子:IteratorTag.java

[java] view
plain copy

print?

package lee;

import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.io.*;

import java.sql.*;

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);

}

}

}

getJspBody()方法返回该标签所包含的标签体:JSPFragment对象,执行该对象的invoke()方法,即可输出标签体内容。

因为该标签的标签体不为空,配置该标签时指定body-content为scripless

[java] view
plain copy

print?

<!-- 定义第三个标签 -->

<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>

使用标签:iteratorTag.jsp

[java] view
plain copy

print?

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<%@ page import="java.util.*"%>

<!-- 导入标签库,指定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>

<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>

2.11.6以页面片段作为属性的标签

*标签处理类中定义类型为JspFragment的属性,该属性代表了“页面片段”;

*使用标签库时,通过<jsp:attribute.../>动作指令为标签的属性指定值。

例子:FragmentTag.java

[java] view
plain copy

print?

package lee;

import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.io.*;

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");

}

}

配置标签:

[html] view
plain copy

print?

<tag>

<!-- 定义标签名 -->

<name>fragment</name>

<!-- 定义标签处理类 -->

<tag-class>lee.FragmentTag</tag-class>

<!-- 指定该标签不支持标签体 -->

<body-content>empty</body-content>

<!-- 定义标签属性:fragment -->

<attribute>

<name>fragment</name>

<required>true</required>

<fragment>true</fragment>

</attribute>

</tag>

由于该标签需要一个fragment 属性,该属性的类型为JSPFragment,因此使用该标签时需要使用<jsp:attribute.../>动作指令来设置属性值。

[java] view
plain copy

print?

<%@ 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>

<mytag:fragment>

<!-- 使用jsp:attribute标签传入fragment参数 -->

<jsp:attribute name="fragment">

<!-- 下面是动态的JSP页面片段 -->

<mytag:helloWorld/>

</jsp:attribute>

</mytag:fragment>

<br/>

<mytag:fragment>

<jsp:attribute name="fragment">

<!-- 下面是动态的JSP页面片段 -->

${pageContext.request.remoteAddr}

</jsp:attribute>

</mytag:fragment>

</html>

2.11.7 动态属性的标签

我们需要传入自定义标签的属性个数是不确定的,属性名也不确定,这就需要借助于动态属性的标签了。

动态属性标签额外要求:

*标签处理类还需要实现DynamicAttributes接口。

*配置标签时通过<dynamic-attributes.../>子元素指定该标签支持动态属性。

例子:DynamicAttributesTag.java

[java] view
plain copy

print?

package lee;

import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.io.*;

import java.util.*;

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 );

}

}

实现DynamicAttributesTag接口的setDynaAttribute()方法,该方法用于为该标签处理类动态地添加属性名和属性值。

配置标签:

[html] view
plain copy

print?

<!-- 定义接受动态属性的标签 -->

<tag>

<name>dynaAttr</name>

<tag-class>lee.DynaAttributesTag</tag-class>

<body-content>empty</body-content>

<!-- 指定支持动态属性 -->

<dynamic-attributes>true</dynamic-attributes>

</tag>

使用该标签;dynaAttrTag.jsp

[java] view
plain copy

print?

<%@ 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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: