自定义JSP标签.docx

上传人:b****4 文档编号:5143126 上传时间:2023-05-08 格式:DOCX 页数:22 大小:119.25KB
下载 相关 举报
自定义JSP标签.docx_第1页
第1页 / 共22页
自定义JSP标签.docx_第2页
第2页 / 共22页
自定义JSP标签.docx_第3页
第3页 / 共22页
自定义JSP标签.docx_第4页
第4页 / 共22页
自定义JSP标签.docx_第5页
第5页 / 共22页
自定义JSP标签.docx_第6页
第6页 / 共22页
自定义JSP标签.docx_第7页
第7页 / 共22页
自定义JSP标签.docx_第8页
第8页 / 共22页
自定义JSP标签.docx_第9页
第9页 / 共22页
自定义JSP标签.docx_第10页
第10页 / 共22页
自定义JSP标签.docx_第11页
第11页 / 共22页
自定义JSP标签.docx_第12页
第12页 / 共22页
自定义JSP标签.docx_第13页
第13页 / 共22页
自定义JSP标签.docx_第14页
第14页 / 共22页
自定义JSP标签.docx_第15页
第15页 / 共22页
自定义JSP标签.docx_第16页
第16页 / 共22页
自定义JSP标签.docx_第17页
第17页 / 共22页
自定义JSP标签.docx_第18页
第18页 / 共22页
自定义JSP标签.docx_第19页
第19页 / 共22页
自定义JSP标签.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

自定义JSP标签.docx

《自定义JSP标签.docx》由会员分享,可在线阅读,更多相关《自定义JSP标签.docx(22页珍藏版)》请在冰点文库上搜索。

自定义JSP标签.docx

自定义JSP标签

自定义JSP标签

自定义标签技术是在JSP1.1版本中才出现的,它允许开发人员创建客户化的标签,并且在JSP文件中使用这些标签,这样可以使JSP代码更加简洁。

这些可重用的标签能处理复杂的逻辑运算和事务,或者能定义JSP网页的输出内容和格式。

本次课将结合具体的范例,详细介绍自定义标签的创建过程,以及它在JSP文件中的使用方法。

1自定义JSP标签简介

JSP标签包括以下几种形式。

(1)主体内容和属性都为空的标签,例如:

hello/>

hello>

hello>

(2)包含属性的标签,例如:

messagekey=”hello.hi”/>

(3)包含主体内容的标签,例如:

greeting>Howareyou.

greeting>

以上

greeting>称为标签的起始标志,

greeting>称为标签的结束标志,两个标签之间的内容“Howareyou.”称为标签主体。

(4)包含属性和主体内容的标签,例如:

greetingusername=”Tom”>Howareyou.

greeting>

(5)嵌套的标签,例如:

greeting>

choose>

when>

when>

choose>

username=”Tom”age=”18”/>

greeting>

以上外层标签

greeting>称为父标签,内层标签

user>称为子标签。

为了便于组织和管理标签,可以把一组功能相关的标签放在同一个标签库中。

开发包含自定义标签的标签库包括以下步骤:

(1)创建自定义标签的处理类(TagHandlerClass)。

(2)创建TLD标签库描述文件(TagLibraryDescriptor)。

假定甲方开发了重用性比较高的标签库,那么除了甲方本身的Web应用可以使用它,其他方(如乙方)也可以使用它。

JSTLCore标签库的使用介绍了如何在Web应用中使用由第三方提供的JSP标准标签库(JSTL)。

本次课将按照如下步骤在Web应用中使用标签库:

(1)把标签处理类及相关类的class文件存放在WEB-INF/classes目录下。

(2)把TLD标签库描述文件存放在WEB-INF目录或者其自定义的子目录下。

(3)在web.xml文件中声明所引用的标签库。

(4)在JSP文件中使用标签库中的标签。

2JSPTagAPI

Servlet容器在运行JSP文件时,如果遇到自定义标签,就会调用这个标签的处理类(TagHandlerClass)的相关方法。

标签处理类可以继承JSPTagAPI中的TagSupport类或者BodyTagSupport类。

JSPTagAPI位于javax.servlet.jsp.tagext包中,图13-1是其中的主要接口和类的类框图。

图13-1JSPTagAPI

2.1JspTag接口

所有的标签处理类都要实现JspTag接口。

这个接口只是一个标识接口,没有任何方法,主要是作为Tag和SimpleTag接口的共同接口。

在JSP2.0以前,所有的标签处理类都要实现Tag接口,实现该接口的标签称为传统标签(ClassicTag)。

JSP2.0提供了SimpleTag接口,实现该接口的标签称为简单标签(SimpleTag)。

本章将介绍传统标签的用法。

2.2Tag接口

Tag接口定义了所有传统标签处理类都要实现的基本方法,包括以下几种。

●setPageContext(PageContextpc):

由Servlet容器调用该方法,向当前标签处理对象(即Tag对象)传递当前的PageContext对象。

●setParent(Tagt):

由Servlet容器调用该方法,向当前Tag对象传递父标签的Tag对象。

●getParent():

返回Tag类型的父标签的Tag对象。

●release():

当Servlet容器需要释放Tag对象占用的资源时,会调用此方法。

●doStartTag():

当Servlet容器遇到标签的起始标志时,会调用此方法。

doStartTag()方法返回一个整数值,用来决定程序的后续流程。

它有两个可选值,即Tag.SKIP_BODY和Tag.EVAL_BODY_INCLUDE。

Tag.SKIP_BODY表示标签之间的主体内容被忽略,Tag.EVAL_BODY_INCLUDE表示标签之间的主体内容被正常执行。

例如对于以下代码:

mytag>

HelloWorld

……

mytag>

假若标签的处理对象的doStartTag()方法返回Tag.SKIP_BODY,那么“HelloWorld”字符串不会显示在网页上;若返回Tag.EVAL_BODY_INCLUDE,那么“HelloWorld”字符串将显示在网页上。

●doEndTag():

当Servlet容器遇到标签的结束标志时,就会调用doEndTag()方法。

doEndTag()方法也返回一个整数值,用来决定程序后续流程。

它有两个可选值,即Tag.SKIP_PAGE和Tag.EVAL_PAGE。

Tag.SKIP_PAGE表示立刻停止执行标签后面的JSP代码,网页上未处理的静态内容和Java程序片段均被忽略,任何已有的输出内容立刻返回到客户的浏览器上。

Tag.EVAL_PAGE表示按正常的流程继续执行JSP文件按。

以上提到的Tag.SKIP_BODY、Tag.EVAL_BODY_INCLUDE、Tag.SKIP_PAGE和Tag.EVAL_PAGE是在Tag接口中定义的4个int类型的静态常量,用于指示标签处理流程。

标签处理类的对象(Tag对象)由Servlet容器负责创建。

Servlet容器在执行JSP文件时,如果遇到JSP文件中的自定义标签,就会寻找缓存中的相关的Tag对象,如果还不存在,就创建一个Tag对象,把它放在缓存中,以便下次处理自定义标签时重复使用。

当Servlet容器得到了Tag对象后,会按照如图13-2所示的流程调用Tag对象的相关方法:

(1)Servlet容器调用Tag对象的setPageContext()和setParent()方法,把当前JSP页面的PageContext对象及父标签处理对象传给当前Tag对象。

如果不存在父标签,则把父标签处理对象设为null。

(2)Servlet容器调用Tag对象的一系列set方法,设置Tag对象的属性。

如果标签没有属性,则无需这个步骤。

(3)Servlet容器调用Tag对象的doStartTag()方法。

(4)如果doStartTag()方法返回Tag.SKIP_BODY,就不执行标签主体的内容;如果doStartTag()方法返回Tag.EVAL_BODY_INCLUDE,就执行标签主体的内容。

(5)Servlet容器调用Tag对象的doEndTag()方法。

(6)如果doEndTag()方法返回Tag.SKIP_PAGE,就不执行标签后续的JSP代码;如果doEndTag()方法返回Tag.EVAL_PAGE,就执行标签后续的JSP代码。

图13-2Servlet容器调用Tag对象的相关方法的流程

注:

一个Tag对象在被创建后,就会一直存在,可以被Servlet容器重复调用。

当Web应用终止时,Serlvet容器会先调用该Web应用中的所有Tag对象的release()方法,然后销毁这些Tag对象。

2.3IterationTag接口

IterationTag接口继承自Tag接口,IterationTag接口增加了重复执行标签主体内容的功能。

IterationTag接口定义了一个doAfterBody()方法,Servlet容器在执行完标签主体内容后,会调用此方法。

如果Serlvet容器未执行标签主体内容,那么就不会调用此方法。

doAfterBody()方法也返回一个整数值,用来决定程序后续流程,它有两个可选值:

Tag.SKIP_BODY和IterationTag.EVAL_BODY_AGAIN。

Tag.SKIP_BODY表示不再执行标签主体内容;IterationTag.EVAL_BODY_AGAIN表示重复执行标签主体内容。

IterationTag接口还定义了一个可作为doAfterBody()方法的返回值得int类型的静态常量:

IterationTag.EVAL_BODY_AGAIN,用于指示Servlet容器重复执行标签主体内容。

Servlet容器在处理JSP文件中的这种标签时,会寻找缓存中的相关的IterationTag对象,如果还不存在,就创建一个IterationTag对象,把它放在缓存中,以便下次处理自定义标签时重复使用。

Servlet容器在得到了IterationTag对象后,会按照如图13-3所示的流程调用IterationTag对象的相关方法:

(1)Servlet容器调用IterationTag对象的setPageContext()和setParent()方法,把当前JSP页面的PageContext对象及父标签处理对象传给当前IterationTag对象。

如果不存在父标签,则把父标签处理对象设为null。

(2)Servlet容器调用IterationTag对象的一系列set方法,设置Tag对象的属性。

如果标签没有属性,则无需这个步骤。

(3)Servlet容器调用IterationTag对象的doStartTag()方法。

(4)如果doStartTag()方法返回Tag.SKIP_BODY,就不执行标签主体的内容;如果doStartTag()方法返回Tag.EVAL_BODY_INCLUDE,就执行标签主体的内容。

(5)如果在步骤(4)中Servlet容器执行了标签主体的内容,那么就调用doAfterBody()方法。

(6)如果doAfterBody()方法返回Tag.SKIP_BODY,就不再执行标签主体的内容;如果doAfterBody()方法返回IterationTag.EVAL_BODY_AGAIN,就继续重复执行标签主体的内容。

(7)Servlet容器调用IterationTag对象的doEndTag()方法。

(8)如果doEndTag()方法返回Tag.SKIP_PAGE,就不执行标签后续的JSP代码;如果doEndTag()方法返回Tag.EVAL_PAGE,就执行标签后续的JSP代码。

与Servlet容器调用Tag对象的流程相比,可以看出,以上步骤(5)和步骤(6)是增加的步骤。

图13-3Servlet容器调用IterationTag对象的相关方法的流程

2.4BodyTag接口

BodyTag接口继承自IterationTag接口,增加了直接访问和操纵标签主体内容的功能。

BodyTag接口定义了两个方法。

●setBodyContent(BodyContentbc):

Servlet容器通过此方法向BodyTag对象传递一个用于缓存标签主体的执行结果的BodyConent对象。

●doInitBody():

当Servlet容器调用完setBodyContent()方法之后,在第一次执行标签主体之前,先调用此方法,该方法用于为执行标签主体做初始化工作。

只要符合以下两种条件之一,setBodyContent(BodyContentbc)和doInitBody()就不会被Servlet容器调用:

●标签主体为空。

●doStartTag()方法的返回值为Tag.SKIP_BODY或者Tag.EVAL_BODY_INCLUDE。

只有同时符合以下两个条件,Servlet容器才会调用setBodyContent(BodyContentbc)和doInitBody()方法:

●标签主体不为空。

●doStartTag()方法的返回值为BodyTag.EVAL_BODY_BUFFERED。

以上提到的BodyTag.EVAL_BODY_BUFFERED是在BodyTag接口中定义的int类型的静态常量,它可作为doStartTag()方法的返回值,指示Servlet容器调用BodyTag对象的setBodyContent()和doInitBody()方法。

Servlet容器在处理JSP文件中的这种标签时,会寻找缓存中的相关的BodyTag对象,如果还不存在,就创建一个BodyTag对象,把它放在缓存中,以便下次处理自定义标签时重复使用。

Servlet容器在得到了BodyTag对象后,会按照如图13-4所示的流程调用BodyTag对象的相关方法:

(1)Servlet容器调用BodyTag对象的setPageContext()和setParent()方法,把当前JSP页面的PageContext对象及父标签处理对象传给当前BodyTag对象。

如果不存在父标签,则把父标签处理对象设为null。

(2)Servlet容器调用BodyTag对象的一系列set方法,设置Tag对象的属性。

如果标签没有属性,则无需这个步骤。

(3)Servlet容器调用BodyTag对象的doStartTag()方法。

(4)如果doStartTag()方法返回Tag.SKIP_BODY,就不执行标签主体的内容;如果doStartTag()方法返回Tag.EVAL_BODY_INCLUDE,就执行标签主体的内容;如果doStartTag()方法返回BodyTag.EVAL_BODY_BUFFERED,就先调用setBodyContent()和doInitBody()方法,再执行标签主体的内容。

(5)如果在步骤(4)中Servlet容器执行了标签主体的内容,那么就调用doAfterBody()方法。

(6)如果doAfterBody()方法返回Tag.SKIP_BODY,就不再执行标签主体的内容;如果doAfterBody()方法返回IterationTag.EVAL_BODY_AGAIN,就继续重复执行标签主体的内容。

(7)Servlet容器调用BodyTag对象的doEndTag()方法。

(8)如果doEndTag()方法返回Tag.SKIP_PAGE,就不执行标签后续的JSP代码;如果doEndTag()方法返回Tag.EVAL_PAGE,就执行标签后续的JSP代码。

图13-4Servlet容器调用BodyTag对象的相关方法的流程

2.5TagSupport类和BodyTagSupport类

TagSupport类和BodyTagSupport类是标签实现类,其中TagSupport类实现了IterationTag接口,而BodyTagSupport类则继承自TagSupport类,并且实现了BodyTag接口。

用户自定义的标签处理类可以继承TagSupport类或者BodyTagSupport类。

例程13-1是TagSupport类的部分源代码。

例程13-1TagSupport.java

importjava.io.Serializable;

importjava.util.Enumeration;

importjava.util.Hashtable;

importjavax.servlet.jsp.JspException;

importjavax.servlet.jsp.PageContext;

importjavax.servlet.jsp.tagext.IterationTag;

importjavax.servlet.jsp.tagext.Tag;

publicclassTagSupportimplementsIterationTag,Serializable{

publicstaticfinalTagfindAncestorWithClass(Tagfrom,

@SuppressWarnings("unchecked")Classklass){

booleanisInterface=false;

if(from==null

||klass==null

||(!

Tag.class.isAssignableFrom(klass)&&!

(isInterface=klass

.isInterface()))){

returnnull;

}

for(;;){

Tagtag=from.getParent();

if(tag==null){

returnnull;

}

if((isInterface&&klass.isInstance(tag))

||klass.isAssignableFrom(tag.getClass()))

returntag;

else

from=tag;

}

}

publicTagSupport(){

}

publicintdoStartTag()throwsJspException{

returnSKIP_BODY;

}

publicintdoEndTag()throwsJspException{

returnEVAL_PAGE;

}

publicintdoAfterBody()throwsJspException{

returnSKIP_BODY;

}

publicvoidrelease(){

parent=null;

id=null;

if(values!

=null){

values.clear();

}

values=null;

}

publicvoidsetParent(Tagt){

parent=t;

}

publicTaggetParent(){

returnparent;

}

publicvoidsetId(Stringid){

this.id=id;

}

publicStringgetId(){

returnid;

}

publicvoidsetPageContext(PageContextpageContext){

this.pageContext=pageContext;

}

publicvoidsetValue(Stringk,Objecto){

if(values==null){

values=newHashtable();

}

values.put(k,o);

}

publicObjectgetValue(Stringk){

if(values==null){

returnnull;

}else{

returnvalues.get(k);

}

}

publicvoidremoveValue(Stringk){

if(values!

=null){

values.remove(k);

}

}

publicEnumerationgetValues(){

if(values==null){

returnnull;

}

returnvalues.keys();

}

privateTagparent;

privateHashtablevalues;

protectedStringid;

protectedPageContextpageContext;

}

TagSupport类的主要方法参见表13-1。

表13-1TagSupport类的主要方法

方法

属性

doStartTag()

当Servlet容器遇到自定义标签的起始标志时调用该方法

doEndTag()

当Servlet容器遇到自定义标签的结束标志时调用该方法

setValue(Stringkey,Objectvalue)

在标签处理对象中设置key/value

getValue(Stringkey)

根据参数key返回匹配的value

removeValue(Stringkey)

在标签处理对象中删除key/value

setPageContext(PageContextpc)

设置PageContext对象,该方法由Servlet容器在调用doStartTag()方法前调用

setParent(Tagt)

设置父标签的处理对象,该方法由Servlet容器在调用doStartTag()方法前调用

getParent()

返回父标签的处理对象

1、parent和pageContext成员变量

TagSupport类有两个重要的成员变量。

●parent:

private访问级别的成员变量,代表父标签的处理对象。

●pageContext:

protected访问级别的成员变量,代表当前JSP页面的PageContext对象。

Servlet容器在调用doStartTag()方法前,会先调用setPageContext()和setParent()方法,设置pageContext和parent成员变量,因此在TagSupport子类的doStartTag()或doEndTag()等方法中可以通过getParent()方法获取父标签的处理对象。

在TagSupport类中定义了protected访问级别的pageContext成员变量,因此在TagSupport子类的doStartTag()或doEndTag()等方法中可以直接访问pageContext变量。

JSP课程中(PageContext抽象类)已经介绍了PageContext类的作用,它在标签处理类中将大有用武之地。

在本章及下一章的标签处理类的例子中,都会用到PageContext类。

注:

在TagSupport的构造方法中不能访问pageContext成员变量,因为此时Servlet容器还没有调用setPageContext()方法对pageContext成员变量进行初始化。

2、处理标签的方法

对于用户自定义的标签处理类,主要重新实现TagSupport类中的以下方法。

●doStartTag():

提供Servlet容器在遇到标签起始标志时执行的操作。

●doEndTag():

提供Servlet容器在遇到标签结束标志时执行的操作。

如果希望Servlet容器重复执行标签主体的内容,那么还可以重新实现TagSupport类的doAfterBody()方法。

3、用户自定义的标签属性

如果在标签中包含自定义的属性,例如:

mytagusername

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 职业教育 > 职业技术培训

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2