本文摘自:李刚 著 《轻量级 Java EE企业应用实战 Struts2+Spring+hibernate整合开发》
续JSP2自定义标签(一)
前面的简单标签既没有属性也没有标签体,用法功能都比较简单。实际上还有如下两种标签:带属性的标签和带标签体的标签。
正如前面介绍的带属性的标签必须为每个属性提供对应的setter和getter方法,带属性的标签的配置方法也和简单标签略有区别。
下面就是一个带属性标签的示例:
package ppp;
import java.io.IOException;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class QueryTag extends SimpleTagSupport {
// 标签的属性
private String driver;
private String url;
private String user;
private String pass;
private String sql;
// 执行数据访问属性
private Connection conn = null;
private Statement stmt = null;
private ResultSet rs = null;
private ResultSetMetaData rsmd = null;
// 各个属性的getter和setter方法
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
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();
}
}
}
}
上面的这个标签包含了5个属性,程序需要为这5个属性提供setter和getter方法。
该标签的内容依然由doTag()方法来决定,该方法会根据SQL语句查询数据库,并将查询结果显示在当前页中。
对于有属性的标签,需要为tag元素增加attribute子元素定义一个属性。attribute子元素通常还需要指定如下子元素:
(1)name:设置属性名,子元素的值是字符串的内容。
(2)required:设置该属性是否为必须属性,该子元素的值为true或者false。
(3)fragment:该属性值是否支持JSP脚本、表达式等动态内容,子元素的值是true或者false。
为配置上面的QueryTag标签,我们需要在mytaglib.tld文件中增加如下配置片段:
<!--定义标签-->
<tag>
<!--定义标签名-->
<name>iterator</name>
<!--定义标签处理类-->
<tag-class>ppp.IteratorTag</tag-class>
<!--定义标签体不允许出现JSP脚本-->
<body-content>scriptless</body-content>
<!--配置标签属性:driver-->
<attribute>
<name>driver</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
<!--配置标签属性:uri-->
<attribute>
<name>uri</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
<!--配置标签属性:user-->
<attribute>
<name>user</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
<!--配置标签属性:pass-->
<attribute>
<name></name>
<required>true</required>
<fragment>true</fragment>
</attribute>
<!--配置标签属性:sql-->
<attribute>
<name>sql</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
</tag>
上面标签分别配置了driver、uri、user、pass、sql五个属性,并且指定这五个属性是必须属性,而且属性支持动态内容。
配置完毕后,就可以在页面中使用该标签了,先导入标签库,再使用标签。使用标签的JSP页面片段如下:
在JSP页面中只需要使用简单的标签就能够完成“复杂”的功能:执行数据库查询,并将查询结果在页面中以表格形式显示出来。这也正是自定义标签库的目的——以简单的标签,隐藏复杂的逻辑。
当然并不推荐在标签处理类中访问数据库,因为标签库是表现层组件,它不应该包含任何业务逻辑实现代码,更不应该执行数据库访问,它只应该负责显示逻辑。
注意:JSTL是Sun公司提供的一套标签库,这套标签库功能非常强大。另外,DisplayTag是Apache组织下的一套开源标签库,主要用于生成页面并显示效果。