jsp2x自定义标签.docx
- 文档编号:6007640
- 上传时间:2023-01-02
- 格式:DOCX
- 页数:16
- 大小:89.20KB
jsp2x自定义标签.docx
《jsp2x自定义标签.docx》由会员分享,可在线阅读,更多相关《jsp2x自定义标签.docx(16页珍藏版)》请在冰豆网上搜索。
jsp2x自定义标签
利用JSP2提供的SimpleTagSupport开发自定义标签
(转自:
)
自定义标签库并不是JSP2才出现的,JSP1.1版中已经增加了自定义标签库规范,自定义标签库是一种非常优秀的表现层组件技术。
通过使用自定义标签库,可以在简单的标签中封装复杂的功能。
为什么要使用自定义标签呢?
主要是为了取代丑陋的JSP脚本。
在HTML页面中插入JSP脚本有如下几个坏处:
JSP脚本非常丑陋,难以阅读。
JSP脚本和HTML代码混杂,维护成本高。
HTML页面中嵌入JSP脚本,导致美工人员难以参与开发。
出于以上三点的考虑,我们需要一种可在页面中使用的标签,这种标签具有和HTML标签类似的语法,但由可以完成JSP脚本的功能——这种标签就是JSP自定义标签。
在JSP1.1规范中开发自定义标签库比较复杂,JSP2规范简化了标签库的开发,在JSP2中开发标签库只需如下几个步骤:
开发自定义标签处理类;
建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库对应多个标签;
在JSP文件中使用自定义标签。
开发自定义标签类
标签库和实际开发
标签库是非常重要的技术,通常来说,初学者、普通开发人员自己开发标签库的机会很少,但如果希望成为高级程序员,或者希望开发通用框架,就需要大量开发自定义标签了。
所有的MVC框架,如Struts2、SpringMVC、JSF等都提供了丰富的自定义标签。
当我们在JSP页面使用一个简单的标签时,底层实际上由标签处理类提供支持,从而可以使用简单的标签来封装复杂的功能,从而使团队更好地协作开发(能让美工人员更好地参与JSP页面的开发)。
早期JSP自定义标签类开发过程略微复杂一些,但JSP2已经简化了这个过程,它只要自定义标签类都必须继承一个父类:
javax.servlet.jsp.tagext.SimpleTagSupport,除此之外,JSP自定义标签类还有如下要求。
如果标签类包含属性,每个属性都有对应的getter和setter方法。
重写doTag()方法,这个方法负责生成页面内容。
下面开发一个最简单的自定义标签,该标签负责在页面上输出HelloWorld。
// 标签处理类,继承 SimpleTagSupport 父类
public class HelloWorldTag extends SimpleTagSupport
{
// 重写 doTag 方法,该方法在标签结束生成页面内容
public void doTag()throws JspException,
IOException
{
// 获取页面输出流,并输出字符串
getJspContext().getOut().write("Hello World");
}
}
上面这个标签处理类非常简单,它继承了SimpleTagSupport父类,并重写doTag()方法,而doTag()方法则负责输出页面内容。
该标签没有属性,因此无须提供setter和getter方法。
建立TLD文件
TLD是TagLibraryDefinition的缩写,即标签库定义,文件的后缀是tld,每个TLD文件对应一个标签库,一个标签库中可包含多个标签,TLD文件也称为标签库定义文件。
标签库定义文件的根元素是taglib,它可以包含多个tag子元素,每个tag子元素都定义一个标签。
通常我们可以到Web容器下复制一个标签库定义文件,并在此基础上进行修改即可。
例如Tomcat6.0,在webapps\examples\WEB-INF\jsp2路径下包含了一个jsp2-example-taglib.tld文件,这就是示范用的标签库定义文件。
将该文件复制到Web应用的WEB-INF/路径,或WEB-INF的任意子路径下,并对该文件进行简单修改,修改后的mytaglib.tld文件代码如下:
xml version="1.0" encoding="GBK"?
>
xmlns: xsi="http: //www.w3.org/2001/XMLSchema-instance" xsi: schemaLocation=" web-jsptaglibrary_2_0.xsd" version="2.0"> -- 定义该标签库的URI --> //www.crazyit.org/mytaglib -- 定义第一个标签 --> -- 定义标签名 --> -- 定义标签处理类 --> -- 定义标签体为空 -->
上面标签库定义文件也是一个标准的XML文件,该XML文件的根元素是taglib元素,因此我们每次编写标签库定义文件都直接添加该元素即可。
taglib下有三个子元素:
tlib-version:
指定该标签库实现的版本,这是一个作为标识的内部版本号,对程序没有太大的作用。
short-name:
该标签库的默认短名,该名称通常也没有太大的用处。
uri:
这个属性非常重要,它指定该标签库的URI,相当于指定该标签库的唯一标识。
如上粗体字代码所示,JSP页面中使用标签库时就是根据该URI属性来定位标签库的。
除此之外,taglib元素下可以包含多个tag元素,每个tag元素定义一个标签,tag元素下至少应包含如下三个子元素:
name:
该标签库的名称,这个属性很重要,JSP页面中就是根据该名称来使用此标签的。
tag-class:
指定标签的处理类,毋庸置疑,这个属性非常重要,指定了标签由哪个Java类来处理。
body-content:
这个属性也很重要,它指定标签体内容。
该元素的值可以是如下几个:
tagdependent:
指定标签处理类自己负责处理标签体。
empty:
指定该标签只能作用空标签使用。
scriptless:
指定该标签的标签体可以是静态HTML元素,表达式语言,但不允许出现JSP脚本。
JSP:
指定该标签的标签体可以使用JSP脚本。
实际上由于JSP2规范不再推荐使用JSP脚本,所以JSP2自定义标签的标签体中不能包含JSP脚本。
所以实际上body-content元素的值不可以是JSP。
定义了上面的标签库定义文件后,将标签库文件放在Web应用的WEB-INF路径,或任意子路径下,JavaWeb规范会自动加载该文件,则该文件定义的标签库也将生效。
使用标签库
在JSP页面中确定指定标签需要2点:
标签库URI:
确定使用哪个标签库。
标签名:
确定使用哪个标签。
使用标签库分成以下两个步骤:
导入标签库:
使用taglib编译指令导入标签库,就是将标签库和指定前缀关联起来。
使用标签:
在JSP页面中使用自定义标签。
taglib的语法格式如下:
<%@ taglib uri="tagliburi" prefix="tagPrefix" %>
其中uri属性确定标签库的URI,这个URI可以确定一个标签库。
而prefix属性指定标签库前缀,即所有使用该前缀的标签将由此标签库处理。
使用标签的语法格式如下:
tagName tagAttribute=”tagValue” … >
tagName>
如果该标签没有标签体,则可以使用如下语法格式:
tagName tagAttribute=”tagValue” … /> 上面使用标签的语法里都包含了设置属性值,前面我们介绍的HelloWorldTag标签没有任何属性,所以使用该标签只需用 helloWorld/>即可。 其中mytag是taglib指令为标签库指定的前缀,而helloWorld是标签名。 下面是使用helloWorld标签的JSP页面代码: <%@ page contentType="text/html; charset=GBK"%> -- 导入标签库,指定mytag前缀的标签, 由http: //www.crazyit.org/mytaglib的标签库处理 --> <%@ taglib uri="http: //www.crazyit.org/mytaglib" prefix="mytag"%>
下面显示的是自定义标签中的内容
-- 使用标签 ,其中mytag是标签前缀,根据taglib的编译指令,
mytag前缀将由http:
//www.crazyit.org/mytaglib的标签库处理 -->
helloWorld/> 上面页面中第一行粗体字代码指定了http: //www.crazyit.org/mytaglib标签库的前缀为mytag,第二行粗体字代码表明使用mytag前缀对应标签库里的helloWorld标签。 浏览该页面将看到如图1所示效果: 图1.简单标签 带属性的标签 前面的简单标签既没有属性,也没有标签体,用法、功能都比较简单。 实际上还有如下两种常用的标签: 带属性的标签。 带标签体的标签。 正如前面介绍的,带属性标签必须为每个属性提供对应的setter和getter方法。 带属性标签的配置方法与简单标签也略有差别,下面介绍一个带属性标签的示例: 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; //标签属性driver的setter方法 public void setDriver(String driver) { this.driver = driver; } //标签属性url的setter方法 public void setUrl(String url) { this.url = url; } //标签属性user的setter方法 public void setUser(String user) { this.user = user; } //标签属性pass的setter方法 public void setPass(String pass) { this.pass = pass; } //标签属性driver的getter方法 public String getDriver() { return (this.driver); } //标签属性url的getter方法 public String getUrl() { return (this.url); } //标签属性user的getter方法 public String getUser() { return (this.user); } //标签属性pass的getter方法 public String getPass() { return (this.pass); } //标签属性sql的getter方法 public String getSql() { return (this.sql); } //标签属性sql的setter方法 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(" //遍历结果集 while (rs.next()) { out.write(" //逐列输出查询到的数据 for (int i = 1 ; i <= columnCount ; i++ ) { out.write(" out.write(rs.getString(i)); out.write(" } out.write(" } } 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子元素定义一个属性,attribue子元素通常还需要指定如下几个子元素: name: 设置属性名,子元素的值是字符串内容。 required: 设置该属性是否为不需属性,该子元素的值是true或false。 fragment: 设置该属性是否支持JSP脚本、表达式等动态内容,子元素的值是true或false。 为了配置上面的QueryTag标签,我们需要在mytaglib.tld文件中增加如下配置片段: -- 定义第二个标签 --> -- 定义标签名 --> -- 定义标签处理类 --> -- 定义标签体为空 --> -- 配置标签属性: driver --> -- 配置标签属性: url --> -- 配置标签属性: user --> -- 配置标签属性: pass --> -- 配置标签属性: sql --> 上面5行粗体字代码分别为该标签配置了driver、url、user、pass和sql等5个属性,并指定这5个属性都是必填属性、而且属性值支持动态内容。 配置完毕后,就可在页面中使用标签,先导入标签库,然后使用标签。 使用标签的JSP页面片段如下: -- 导入标签库,指定mytag前缀的标签, 由http: //www.crazyit.org/mytaglib的标签库处理 --> <%@ taglib uri="http: //www.crazyit.org/mytaglib" prefix="mytag"%> ... -- 其他HTML内容 --> -- 使用标签 ,其中mytag是标签前缀,根据taglib的编译指令, mytag前缀将由http: //www.crazyit.org/mytaglib的标签库处理 --> query driver="com.mysql.jdbc.Driver" url="jdbc: mysql: //localhost: 3306/javaee" user="root" pass="32147" sql="select * from newsinf"/> 在浏览器中浏览该页面,效果如图2所示。 图2.使用带属性的标签执行查询 图2中看到从数据库里查询到2条记录,当然这也需要底层javaee数据库里包含newsinf数据表,且该数据表里包含这两条记录才行。 在JSP页面中只需要使用简单的标签,即可完成“复杂”的功能: 执行数据库查询,并将查询结果在页面上以表格形式显示。 这也正是自定义标签库的目的——以简单的标签,隐藏复杂的逻辑。 当然,并不推荐在标签处理类中访问数据库,因为标签库是表现层组件,它不应该包含任何业务逻辑实现代码,更不应该执行数据库访问,它只应该负责显示逻辑。 带标签体的标签 带标签体的标签,可以在标签内嵌入其他内容(包括静态的HTML内容和动态的JSP内容),通常用于完成一些逻辑运算,例如判断和循环等。 下面以一个迭代器标签为示例,介绍带标签体标签的开发过程。 一样先定义一个标签处理类,该标签处理类的代码如下: public class IteratorTag extends SimpleTagSupport { //标签属性,用于指定需要被迭代的集合 private String collection; //标签属性,指定迭代集合元素,为集合元素指定的名称 private String item; //collection属性的setter和getter方法 public v 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。 copyright@ 2008-2022 冰点文档网站版权所有 经营许可证编号:鄂ICP备2022015515号-1");
"); ");"); ");
冰豆网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。