JSP自定义标签开发(三)——标签语言的介绍

JSP标签库(也称自定义库)可看成是一套产生基于XML脚本的方法,它经由JavaBeans来支持。在概念上说,标签库是非常简单和可以重用的代码构造。

 自定义标签有着丰富的特点,它们可以:

1.可以通过调用页面传递的属性进行自定义;

2.可以访问对于JSP页面可能的所有对象;

3.可以修改由调用页面产生的响应。

4.可以相互间通信。你可以创建并初始化一个JavaBean组件,创建一个变量引用标签中的bean,接着在其它的标签中引用该bean.

5.可以在一个标签中嵌套另一个,可以在JSP页面中进行复杂的交互。


 下面的代码声明在网页中使用新的标签,这个标签以hello为前缀,访问的路径为/demotag。

<%@ taglib uri="/demotag" prefix="hello" %>


  自定义标签为在JSP项目中创建易于重用的代码打开了一扇大门。你所需要的只是标签库和它的文档说明。

  通过实现接口或者继承现有的类,我们就可以开发自定义的标签。
常用的接口有:

TagSupport类

  该类是IterationTag的缺省实现。除了实现原有方法外,本身还增加了一些有用的其他方法和成员变量。下表列出其中重要的几个:

名称  描述 
重写的方法和他们的返回值   
void doStartTag()  继承自Tag。返回值SKIP_BODY。 
void doAfterBody()  继承自IterationTag。返回值SKIP_BODY。 
void doEndTag()  继承自Tag。返回值EVAL_PAGE。 
处理嵌套标签的有用的方法   
void setParent(Tag)  接受和维护一个父标签的引用。 
Tag getParent() 返回父标签的引用。 
Tag findAncestorWithClass(Tag,Class)  静态方法。寻找最近的指定类的标签。 
标签属性操作   
void setValue(String,Object)  设置属性。属性名是字符串,值可以是任何对象。 
Object getValue(String)  返回给定属性名的属性的值。 
Enumeration getValues()  返回一个所有值的枚举。 
void removeValue(String)  删除给定的属性。 
受保护的实例变量   
PageContext pageContext  一个保存着PageContext对象的变量。 
 
BodyTagSupport类

 该类同时继承了TagSupport类,并实现BodyTag接口。除了前表所示方法,该类还提供了一些其它方法便于使用。
 

名称  描述 
重写的方法和他们的返回值   
void doStartTag()  继承自Tag。返回值EVAL_BODY_BUFFERED。 
void doAfterBody()  继承自IterationTag。返回值SKIP_BODY。 
void doEndTag()  继承自Tag。返回值EVAL_PAGE。 
用以处理缓冲的方法   
void setBodyContent(BodyContent)  接受和维护一个BodyContent对象(缓冲对象)的引用。 
BodyContent getBodyContent()  返回BodyContent对象的引用。 
JspWriter getPreviousOut()  返回JspWriter对象,BodyContent就是对他的简单包裹。 

实现Tag接口

 所有的标签处理器都需要间接或直接的实现这个接口。

  下面列出Tag接口定义的方法和常量:

方法名  描述 
int doStartTag()   当碰到标签起始标记时执行。() 
int doEndTag()  当碰到标签结束标记时执行。() 
Tag getParent()  获得一个父标签对象 
void release()  从内存中释放该标签对象 
void setPageContext(PageContext)  设置当前页上下文(page context) 
void setParent(Tag)  对父标签对象进行设置 
 

 

常量  描述 
EVAL_BODY_INCLUDE  doStartTag()的返回值。指出jsp引擎计算标记体并输出
SKIP_BODY  doStartTag()的返回值。指出jsp引擎跳过标记体且不输出 
EVAL_PAGE  doEndTag()的返回值。指出jsp引擎计算页面剩余部分并输出 
SKIP_PAGE  doEndTag()的返回值。指出jsp引擎跳过页面剩余部分且不输出 

setPageContext()方法
setPageContext()方法是一个定制标签声明周期内第一个要被调用的方法。完整写法是:
public void setPageContext(PageContext);
jsp引擎会将jsp页转换时隐含创建的pageContext对象,作为参数,调用setPageContext方法。

通常的做法会将这个参数保存为本标记处理器的参数。


setParent()和getParent()方法
当标签嵌套使用时,外层的标签被成为父标签,内部的被称为子标签。完整的写法是:
public void setParent(Tag);
public Tag getParent();
其中setParent方法对父标签对象进行设置。而getParent方法用以获得父标签对象。


setter方法
当定制标签中包含属性时,在标签处理器中有和javaBean相同的设置机制。即每一个属性XXX,都有对应的setXXX()方法。
这些方法的调用是在setPageContext()和setParent()之后,doStartTag()之前。(就是说所有的属性-即实例变量-必须完全赋值,因为随后的方法可能会调用到它们)


doStartTag()方法
该方法标志着真正的标签处理开始。当前三阶段的方法执行完后,jsp引擎就会调用doStartTag()方法了。完整写法是:
public int doStartTag() throws JspException;
该方法给了标签处理器一个初始化计算和校验属性值合法性的机会。如果初始化失败或属性值不合法,则抛出JspException异常,或其子类,如JspTagException。
初始化计算过后,该方法将决定是否继续对标签体进行计算。作为结果,返回一个整数常量(EVAL_BODY_INCLUDE或SKIP_BODY),用以指示是否跳过标签体的执行。除此之外不返回任何其它值。

doEndTag()方法
执行完doStartTag()方法后,就该执行doEndTag()了。完整写法是:
public int doEndTag() throws JspException;
该方法标志着真正的标签处理结束。同样该方法将决定是否继续执行jsp文件中该标签之后的内容。它也会返回一个整数常量(EVAL_PAGE或SKIP_PAGE),用以指示页面后续内容是否跳过。注意此处的范围是页,并不是转换单位。所以计算不计算全都是针对该页而言。

release()方法

最后,jsp引擎将调用release方法,当标签处理结束,标签处理器对象不再使用时。完整写法是:
public void release();
注意。一个页面内同时有多个相同标签时,jsp引擎会只会为该标签创建一个对象。只有等该页内相同标签全部处理完了。jsp引擎才会调用release()方法,将该标签对象从内存清理掉。

  自定义标签的开发包括两个部分的开发:
(1)开发标签的处理程序(java类)
(2)标签描述文件(.tld文件)

  自定义标签的种类有许多,可以根据实际项目的需要进行编写。但为了不重复的开发,jsp标准推出JSTL(标准标签库)。


  在JSP应用程序中添加自定义标签的能力可以使工作重点放到以文档为中心的开发方式上。可以使 Java 代码不出现在 JSP 页中,从而使这些页面更容易维护。

  在创建自定义标签之前,需要创建一个 标签处理程序。标签处理程序是一个执行自定义标签操作的 Java 对象(Java类)。在使用自定义标签时,要导入一个 标签库 —— 即一组标签/标签处理程序对,这样页面编译时才能处理你的自定义标签。通过在 Web 部署描述符(web.xml)中声明库导入它,然后用指令taglib将它导入 JSP 页。

  如果JSP容器在编译JSP文件时遇到了自定义标签,那么它就检查 标签库描述符(tag library descriptor)(TLD) 文件以查询相应的标签处理程序。TLD 文件对于自定义标签处理程序,就像 Web 部署描述符对于 servlet 一样。

  对正文进行操作 —— 即对在开始和结束标签之间的内容进行操作的 —— 标签必须实现 BodyTag 接口。我们将称这些标签为正文标签。我们将不对其正文操作的标签称为简单标签。简单标签可以实现Tag接口,尽管不要求它们这样做。要记住不对其正文操作的标签仍然有正文,只不过,它的标签处理程序不能读取这个正文。
要构建简单标签,我们需要完成以下步骤:

1. 创建实现了Tag接口(准确地说是 javax.servlet.jsp.tagext.Tag)的标签处理程序类。
2. 创建一个 TLD 文件。 
3. 在标签处理程序 Java 类中创建属性。 
4. 在 TLD 文件中定义与标签处理程序 Java 类中定义的属性对应的属性。 
5. 在 TLD 文件中声明 scriptlet 变量。 
6. 实现 doStartTag() 方法。在标签处理程序类中,根据属性将值设置到 scriptlet 变量中。

  在jsp1.2时代已经有标记库了, 并且功能强大,但标记库的编程和调用都比较复杂,导致真正使用到WEB开发中的还是不多。JSP2.0推出的简单标记库扩展解决了以上的问题。简单标记库相对JSP1.2中的标记库来说,优点在于对后台程序员来说,结构更简单,实现接口更少,可以轻松实现后台程序。

  JSP 2.0中加入了新的创建自制标记的API:javax.servlet.jsp.tagext.SimpleTag,该API定义了用来实现简单标记的接口。和JSP 1.2中的已有接口不同的是,SimpleTag接口不使用doStartTag()和doEndTag()方法,而提供了一个简单的doTag()方法。这个方法在调用该标记时只被使用一次。而需要在一个自制标记中实现的所有逻辑过程、循环和对标记体的评估等都在这个方法中实现。从这个方面来讲,SimpleTag可以和IterationTag达到同等的作用。但SimpleTag的方法和处理周期要简单得多。在SimpleTag中还有用来设置JSP内容的setJspBody()和getJspBody()方法。Web容器会使用setJspBody()方法定义一个代表JSP内容的JspFragment对象。实现SimpleTag标记的程序可以在doTag方法中根据需要多次调用getJspBody().invoke()方法以处理JSP内容。

自定义标签的分类:
(1)不带主体和属性的简单标签:如< mytag:helloworld/>
(2)不带主体但有属性的标签:如”/>
(3)带标签体和属性的标签:在自定义标签的起始和结束标签之间的部分为标签体(Body)。Body的内容可以是JSP中的标准标签,也可以是HTML、脚本语言或其他的自定义标签。

 

(4使用脚本变量的标签:
定义了id和type属性的标签可以被标签后面的Scriptlet使用。

<%sqlDB.getConnection(); %>

你可能感兴趣的:(jsp自定义标签专题研究)