Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 753|回复: 0

JSP 自定义Taglib创建

[复制链接]

该用户从未签到

发表于 2011-7-31 22:06:18 | 显示全部楼层 |阅读模式
主要是关于如何将scriptlet转换成自定义标记,并对其进行设置以便在您的JSP开发项目中使用。

为什么使用taglib?

所谓标记库(tag library)是指由在JSP页面中使用的标记所组成的库。JSP容器推出时带有一个小型的、默认的标记库。而自定义标记库是人们为了某种特定的用途或者目的,将一些标记放到一起而形成的一种库。在一个团队中协同工作的开发者们可能会为各自的项目创建一些非常特定化的自定义标记库,同时也会创建一个通用自定义标记库,以供当前使用。

JSP 标记替换了scriptlet,并缓解了由scriptlet所招致的所有令人头痛的事情。例如,您可以看到这样的标记:



[pre]<store:shoppingCart id="1097629"/>[/pre]




或者这样的标记:



[pre]<tools:usageGraph />[/pre]




每个标记都包含了指向一个java类的引用,但是类中的代码仍旧在它该在的地方:在标签之外,一个编译好的类文件之中。






从 scriptlet 到标记

创建一个自定义标记的第一步就是决定您想怎样使用它,如何称呼它,以及它答应使用或者需要什么属性(假如有的话)。对于时间戳标记,我们所需要的很简朴:只要一个能够输出一个页面的最后修改数据的简朴标记。

由于不需要属性,这个标记看上去就是这个样子:



[pre]<site-utils:lastModified />[/pre]




这个标记的名称和前缀是一样的:都是 site-utils 。元素的内容是空的,这意味着该元素中不答应有子元素存在。定义了这个标记之后,接下来的一步就是实现它的行为。






实现行为

实现标记行为的第一步是将scriptlet代码从原先所在的地方移到一个Java类( LastModifiedTag )中,如清单 1 所示:


清单 1. 创建一个时间戳标记

[pre]package com.newInstance.site.tags;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.Servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;
public class LastModifiedTag extends TagSupport {
    public int doEndTag() {
      try {
        HttpServletRequest request =
(HttpServletRequest)pageContext.getRequest();
        String path = pageContext.getServletContext().getRealPath(
          request.getServletPath());
        File file = new File(path);
        DateFormat formatter = DateFormat.getDateInstance(
          DateFormat.LONG);
        pageContext.getOut().println(
          formatter.format(new Date(file.lastModified())));
      } catch (IOException ignored) { }
      return EVAL_PAGE;
    }
}
[/pre]




这个方法中的代码看上去比较认识;实质上,它恰是我们在先前用到的相同的时间戳代码。因为不需要用户输入,而且该标记也没有属性或者嵌入的内容,我们惟一需要关心的一个新方法就是 doEndTag() (),在这个方法中该标记可以输出内容(在这个例子中是最后修改数据)到JSP页面。

清单 1 中其他的更改更多地与作为一个JSP标记的代码有关,而与在一个页面内运行的scriptlet没有多大关系。例如,所有的JSP标记都应该扩展JSP类 javax.servlet.jsp.tagext.TagSupport ,这个类为JSP标记提供了基本框架。可能您还留意到,该标记返回的 EVAL_PAGE . EVAL_PAGE 是一个预定义的整型常量,它指示容器处理页面的剩下部门。另一种选项就是使用 SKIP_PAGE ,它将中止对页面剩下部门的处理。假如您要将控制转移到另一个页面,例如您要前进(forward)或者重定向(redirect)用户,那么只需要使用 SKIP_PAGE 。剩下来的细节都是与时间戳自身有关的事情。

接下来,编译这个类,并将 LastModifiedTag.class 文件放到一个WEB-INF/classes 目录下,留意要放到准确的路径层次结构中。这个路径应该匹配该标记的包名,包名中的圆点(.)用斜杠(/)代替。在本例中,目录的路径是基路径(WEB-INF/classes)再加上层次结构com/newInstance/site/tags。假如有一个名为 foo.bar.tag.MyTag 的标记,那么它将被放在 WEB-INF/classes/foo/bar/tag中。这种路径层次结构确保了Web容器在任何需要装载该标记的时候都能够找到这个类。






创建TLD

接下来的一步是创建一个 标记库描述符(tag library descriptor ,TLD)文件。TLD向容器和任何要使用该标记库的JSP页面描述您的标记库。清单 2 显示了一个非常尺度的TLD,其中只包含了一个标记。当您将更多的标记添加到库中时,TLD文件的长度和复杂性将随之增长。


清单 2. 一个标记库描述符

[pre]<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib
    PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2/EN"
           "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>site-utils</short-name>
    <uri>http://www.newInstance.com/taglibs/site-utils</uri>
    <tag>
      <name>lastModified</name>
      <tag-class>com.newInstance.site.tags.LastModifiedTag</tag-class>
      <body-content>empty</body-content>
    </tag>
</taglib>
[/pre]




TLD 文件顶部的信息应用于整个标记库。在本例中,我提供了一个版本(这对于跟踪某个标记库的JSP创建者拥有哪个版本很有用,尤其是在您需要常常修改标记库的情况下更是如斯);该标记库所依靠的JSP版本;一个为该标记库推荐的前缀;以及用于引用这个标记库的URI。留意,我使用了前缀 short-name 作为URI的一部门,这样 比较轻易将前缀和标记库的URI看成一个整体。

剩下的信息用于一个特定的标记,这些信息用 tag 元素表示。我指定了该标记的名称、用于该标记的类(这个类应该被编译好并放在适当的地方,以便容器能够装载),最后还指定了该标记是否有嵌入的内容。在本例中,标记没有嵌入的内容,因此使用"empty"。

保留这个文件,并将其放到WEB-INF/tlds目录下(您可能需要在您的容器中创建这个目录)。我将这个文件保留为site-utils.tld,并在该标记库的URI(推荐的前缀)和TLD文件本身之间再次创建一个干净的链接。对于这个特定的标记库,要使其可以使用,最后一步要做的是让您的Web应用知道如何连接一个JSP页面中的URI,如何哀求使用一个标记库。这可以通过应用的web.xml文件来做。清单 3 显示了一个非常简朴的web.xml片断,恰是它为我们的标记库做这样的事情。


清单 3. 将一个URI与一个标记库链接起来

[pre]<taglib>
      <taglib-uri>http://www.newInstance.com/taglibs/site-utils</taglib-uri>
      <taglib-location>/WEB-INF/tlds/site-utils.tld</taglib-location>
    </taglib>
[/pre]









包装起来

假如您已经按照上述步骤执行了,那么现在您应该能够在JSP页面中引用新标记了。清单 4 向我们展示了新改进的footer.jsp,这个文件中现在完全没有scriptlet,也没有指向具有scriptlet的JSP页面的引用。


清单 4. 使用新的标记库

[pre]<%@ taglib prefix="site-utils"
             uri="http://www.newInstance.com/taglibs/site-utils" %>
          </td>
          <td width="16" align="left" valign="top"> </td>
    </tr>
    <!-- End main content -->
<!-- Begin footer section -->
    <tr>
      <td width="91" align="left" valign="top" bgcolor="#330066"> </td>
      <td align="left" valign="top"> </td>
      <td class="footer" align="left" valign="top"><div align="center"><br>
        © 2003
        <a href="mailto:webmaster@newInstance.com">Brett McLaughlin</a><br>
        Last Updated: <site-utils:lastModified />
        </div></td>
      <td align="left" valign="top"> </td>
      <td width="141" align="right" valign="top" bgcolor="#330066"> </td>
    </tr>
</table>
<!-- End footer section -->
[/pre]




在前面几期中看了JSTL如何工作(参见“ 利用JSTL更新您的JSP页面”和“ 导入内容到您的Web站点”)之后,接下来该做什么您应该很清晰了:我们通过使用web.xml文件中的URI来引用这个标记库,为之分配一个前缀(来自TLD的 short-name 始终是最好的选择),然后就像使用任何其他JSP标记一样使用这个标记。终极得到的是一个简洁的、更好的JSP页面,这个JSP页面运行起来不比有 scriptlet 的时候差。

当前我们的自定义标记还很简朴,在下一期,我们将扩展其功能。到时候网上见。

FROM:http://www.ibm.com/developerworks/cn/java/j-jsp07233/
回复

使用道具 举报

  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2011-7-31 22:24:00 | 显示全部楼层
    谢谢楼主分享。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-6-7 15:46 , Processed in 0.690905 second(s), 47 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表