使用SimpleTag支持自定义JSP标签

使用Java来开发JSP标记 <转自 http://www.blogjava.net/sam-chi/archive/2010/08/01/327695.html > 


    最近复习JSP中。我们知道JSP是Java WEB的一个规范。在这个规范之内我们可以自己去做很多事情。JSP API提供了接口允许我们自己去自定义JSP标签和EL表达式。自定义JSP标签的大致思想是这样的,实现一个包含标签参数和行为逻辑的类,这个类我们称它为标记处理器类,它实质上是一个Bean,我们设置标签的属性实际上是调用它的setter方法。接下来通过使用标记库描述文件(TLD)来描述标签的相关信息,以便在JSP页面中使用taglib指令时能顺利的找到它。下面我们来看看详细应该怎么去做。
    从JSP2.0开始引入了一个简单标记处理器接口——javax.servlet.jsp.tagext.SimpleTag接口,这个接口取代了原先JSP1.0提供的3个标记处理器接口,我们只需要使用SimpleTarget接口就可以实现所有类型的JSP标记。之所以称之为简单,是因为这样设计让开发者在编写程序上省了不少力气,但是它可以实现很复杂的功能,并不是说它的功能很简单。
    该接口包含了如下5个方法:
    void doTag();  //该方法包含了标签执行的业务逻辑
    JspTag getParent();  //获取该标签的父标签
    setJspBody(JspFragment body); //设置JSP标签体,关于JspFragment类我们稍后再讨论
    setJspContext(JspContext ctx);//设置JSP上下文
    setParent(JspTag parent);  //设置父标签
但是多数情况下我们不需要去亲自实现这个接口,因为作为开发者,我们关心的是业务逻辑,也就是doTag()方法的内容,这种情况我们只需要继承javax.servlet.jsp.tagext.SimpleTagSupport类即可,这个类为我们实现了SimpleTag接口,我们只需要去重写它的doTag()方法。下面我们来实现一个最简单的标签:给标签传递一个参数,让它在页面上显示出来.
首先我们要做的是写一个标记处理器类:

嗯,这是一个继承了SimpleTagSupport类的Bean,一样拥有属性、setter方法。唯一特别的是重写了父类的doTag()方法。在这个doTag()中,我们通过获得一个JSP上下文对象来向页面输出一句话:Hello!XXX。

下面是该介绍JspContext对象的时候了,这是一个抽象类,它唯一的子类是PageContext。这么说刚才所返回的实际对象是PageContext类型的。我们可以对其进行强制转换:PageContext pageCtx = (PageContext)this.getJspContext();

通过PageContext对象我们就可以访问到Request和Response对象了,如:

 

通过这种方式我们就可以在标签处理器中操作WEB应用各个作用域的数据了。

我们都知道在使用JSP标签时要在JSP页面开头使用taglib指令进行声明,如:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
taglib指令通过URL来对标签进行定位。但是它是如何做到的呢?这就要靠TLD了,TLD就是标记库描述文件(Tag Library Descriptor,TLD),我们看JSTL的JAR包中,META-INF文件夹下每个库都有一个对应的部署描述文件。TLD实际上是一个XML文件,里面描述了标记库和其中标记的信息。一个完整的TLD文件结构如下所示:


起始标签是taglib,<tlib-version>定义了taglib的版本号,<short-name>定义了标签库的简称,<uri>定义了URI标识,taglib就是通过此URI来找到相关的标记库的。
接下来的<tag>标签便是定义JSP标签的属性了:
以下是必须的属性
<name>标签名称
<tag-class>标记器类
<body-content>动作体类型,JSP2.0支持如下动作体:
empty 空标记
jsp:可以包含标签、EL和Scriptlet
scriptless:不允许Java脚本内容
tagdependent:对体不进行处理
<attribute>标签定义了标签参数。
其中:
<name>标签指定了参数的名称。
<required>指定了参数是否是必要的。true是必要,false是不必要
<rtexprvalue>指定了是否允许使用表达式(包括EL表达式和Java表达式),true为允许,false为不允许

<funtion>标签定义了EL表达式,我们稍后再做介绍。


如何执行动作体?
我们在编写JSP页面时经常会用到<c:if>和<c:forEach>之类的标签
<c:if test="true">
  <p>条件是真的,执行!</p>
</c:if>
只要满足条件,就会去执行动作体,那么我们怎么在自定义JSP标记中去执行动作体呢?
首先我们先要来研究一个叫做JspFragment的类。JspFragment代表了JSP标签的动作体,我们通过它的invoke方法就可以执行动作体,下面我们来实现一个类似于<c:if>的标签:
 
只要满足了条件,标签动作体就会执行。
invoke方法接受一个java.io.Writer对象,使用这个对象将内容输出到页面,如果不输出则可以给它传递一个null参数。

JSP中引入了EL表达式给我们的开发带来了很大的方便,同自定义标签一样,允许开发者去自定义EL表达式函数,定义EL表达式函数要比定义标签简单多了,我们甚至不需要去实现任何接口,假设我们要实现一个简单的EL表达式函数来计算两个数的和,就可以这样:



这个类中全部是static方法,这是一个工具类。
然后我们只需要在TLD声明即可:


function-signature类似于C语言中的函数声明,通过这个找到到底调用类中哪个工具方法。
使用的时候只需要这样就可以了:${test:add(1,2)}运行时输出结果为3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值