您的位置:首页 > 编程语言 > Java开发

javaweb中对于自定义标签的学习

2007-10-12 15:24 477 查看
我们在Html中已经学习过了<html></html>、<body></body>、<input>等都是标签,当编译器编译了这个标签的时候,就执行了这个标签所表示的功能。比如:编译了<body>标签,就知道了下面的内容是属于一个网页的文档体部分。当编译了</body>标签,就知道了已经结束了一个网页的文档体部分。那么第8章我们学习的Jsp标准动作实际上就是一个标签,也是<jsp:usebean>这样的标签形式,所以,也是实际上这个动作能引入一个javabean的原因是 当编译了这个标签时,就代表了此时要执行引入javabean的方法。
其实,无论是html标签也好,还是jsp中的标签也好。我们很容易就可以想象得出,既然每个标签代表一个具体的操作,那么也就是页面执行到某一个标签的时候,编译器会自动的调用已经编译好的文件中的相应的方法以便来实现该操作。------一定要理解的地方。(1)
在细一点说:比如,当编译到<body>时,编译器知道这是一个文档体的开始部分,也就是这时候要执行一个开始文档体的操作,那么,可能在这个标签所对应的文件中,我要调用一个方法,这个方法的功能就是开始一个文档体。对应的,当编译到</body>时,编译器知道这是一个文档体的结束部分,也就是说,在页面上执行到</body>时,编译器要调用某个方法,这方法的功能就是要结束一个文档体。   ------一定要理解的地方。(2)
那么,如果我们要在jsp页面中实现自定义标签的时候也是一样,对于每个我们自己定义的标签,比如:<rrr> </rrr>是我们定义的自定义标签(随便写的),在页面上,当编译到这个标签的时候,编译器要知道,这个标签要实现什么样的功能,对于这个标签的每个部分,编译器应该调用哪个文件里的哪个方法,所以这一切都是我们要做的。首先,我们要写好这个方法,然后,再在页面里面定义某个标签,这样,才能实现自定义标签实现特定的功能。
------一定要理解的地方。(3)
以上部分实际上自定义标签的原理。
下面我们就要开始制作自己的自定义标签了。
       一.首先,还是要从标签要调用的文件,和标签要调用的方法开始,我们称之为标签处理程序。
1)Jsp中,在javax.servlet.jsp.tagext包中,提供给我们标签处理程序类和接口。我们的自定义的标签处理程序就可以继承自这个包当中的接口。
他们之间的关系:
                                   JspTag-----接口
                                   (所有标签处理程序都要实现的)
Tag(接口)
实现传统标签开发时,要实现的接口

SimpleTag(接口)
实现简单标签开发时,要实现的接口

IterationTag(接口)
实现了Tag接口,新增了可以重复调用标签体的功能,

SimpleTagSupport(类)
实现了SimpleTag接口,用作简单标签处理程序的父类

BodyTag(接口)
继承该接口的标签处理程序可以对标签体执行后的内容进行处理。

TagSupport(类)
作为传统标签处理程序的父类,如处理程序不需访问标签体时,就可继承该类

BodyTagSupport类
作为传统标签处理程序的父类,如处理程序需要访问标签体并要对标签体进行操作的话,就可继承此类

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2)以上就是jsp提供给我们的标签处理程序类,我们可以选择继承
比如我们现在写了一个标签处理程序类TagSupportTest类继承自BodyTagSupport类,那么该类就是一个标签处理程序类,那么比如现在jsp页面上就有这么个标签<uuu>就对应我这个标签处理程序类TagSupportTest,那么,如果页面上执行到<uuu>标签的某个部分时,就会相对应的调用TagSupportTest类中的某个方法。
(下面的内容更加重要,表达了标签和标签处理程序中各个方法之间的对应关系,请注意理解)
好,我们先看看标签,
我们知道标签有这几种:
<br>----这种标签,没有任何属性,
<input type=”text”>---这种标签带有属性
<body bgcolor=”red”>
       hello world
</body>
---读于该标签来讲,即带有属性,又带有标签体,那我们称<body>为开始标签,表示要开始执行这个标签了,</body>为结束标签,表示要结束这个标签了,开始和结束之间内容称为标签体。
那我们就来看看传统标签对应的bodyTag接口里,都有哪些对应标签各个部分的方法呢
public void setPageContext(PageContext pc)
该方法被Jsp页面的实现对象所调用,设置当前页面的上下文。
public void setParent(Tag t)
若标签有嵌套关系,该方法用来设置父标签。
public Tag getParent()
若标签有嵌套关系,该方法用来获取父标签。
 

 

public int doStarTag() throws JspException

当页面内开始执行开始标签时,要相对应的调用该方法
171ab
。(注意标签和标签处理程序之间的联系。)
该方法有三个返回值
1、SKIP_BODY   该返回值表示,Jsp页面内,标签中的标签体部分被忽略过,
2、EVAL_BODY_INCLUDE 该返回值表示,Jsp页面内的标签体部分被执行,执行的结果输出到当前的输出流中。
3、EVAL_BODY_BUFFERED 该返回值表示 在标签处理程序内,创建出BodyContent对象,那么标签的标签体还是要被执行的,但是执行的结果存放在BodyContent对象内。
public int doAfterBody() throws JspException

该方法在每次对标签体的处理完成之后被调用,如果没有标签体要处理,那么这个方法不会被执行。

该方法有两个返回值
1、EVAL_BODY_AGIN

该返回值表示,要重新执行标签体。
2、SKIP_BODY

该返回值表示,忽略标签体,转而执行标签体后面的内容。
 

public int doEndTag() throws JspException

       当页面处理结束标签时,伽方法被调用。

该方法有两个返回值
1、EVAL_PAGE 该返回值表示,接着执行jsp页面内的剩下的内容。
       2、SKIP_PAGE 该返回值表示,Jsp页面的剩下的内容被略过。
 

另外还有,对应于要创建BodyContent对象来讲,还有个方法,
public  void setBodyContent(BodyContent b)

调用该方法,就是为了设置bodyContent属性的,只有当doStartTag()方法的返回值
是EVAL_BODY_BUFFERED时,也就是要将jsp页面中标签体部分的执行结果放置在一个BodyContent对象里时,该方法才会被调用,是用来设置一个BodyContent 对象,以便来存储标签体的执行结果。
上述方法是设置BodyContent对象,那么,还有另外一个方法,是用来初始化BodyContent对象的。
public void doInitBody() throws JspException

在setBodyContent()方法被调用后,标签体第一次被执行之前,该方法被调用,为标签体的执行做好BodyContent的准备。
 

3)、那么,BodyTag接口在Jsp容器内的被调用顺序是这样的,(这地方要注意的,我们现在如果写了一个标签处理程序,这个标签处理程序是由 Jsp容器来调用的,因为我们知道,只有当Jsp页面里相应的标签被执行到了的时候,才会调用相应的标签处理程序当中的方法,所以,要知道的是,这里所说的顺序,也是Jsp容器调用标签处理程序中相对应方法的顺序。图示见书上的图10。3)
1、容器在创建标签处理程序的对象后,(也就是相应的类,是在容器内部完成的)调用setPageContent()方法设置标签的页面上下文。然后调用setParent()方法设置这个标签得父标签。
2、调用标签处理程序的set***()方法,来设置标签里的属性,也就是说,在标签处理程序里,如果存在着属性的时候,我们可以通过这样的set访问器来设置属性的值。
3、调用doStartTag()方法,该方法可以返回Eval_Body_Include (表示执行标签体)、EVAL_BODY_BUFFERED(表示执行标签体,并把标签体的执行结果放入到一个BodyContent对象的里面,所以,若返回值是该值的话,则开始调用setBodyContent()方法,继而调用doInitBody()……)、SKIP_BODY(表示跳过标签体部分,转而直接进入doEndTag()方法的调用)
4、若setBodyContent()方法被调用,则再次方法内,设置标签处理程序中的bodyContent属性,接着调用doInitBody()方法,为执行标签(第一次)做准备,然后就开始执行标签体。
5、执行完标签体之后,开始调用doAfterBody()方法,该方法的返回值是Eval_Body_Aagin(表示重新执行标签体。)、SKIP_BODY(表示不再执行标签体。)
6、调用doEndTag()方法,该方法是在结束了标签体执行后备调用,它的返回值是EVAL_PAGE(表示执行JSP页面剩下的内容)、SKIP_PAGE(表示跳过JSP页面内剩下的内容。)
7、当需要释放标签处理程序的实例时,调用release()方法。
 

 

二、以上我们学习的是标签处理程序,那么下面我们就要在JSP页面内创建自己的自定义标签了。但是,在这之前还有一项工作要做,就是,我们要往JSP页面内创建的自定义标签到底对应哪个标签处理文件是不知道的,所以我们要创建一个标签库描述符以便让JSP标签找到相对应的标签处理程序。

------一定要理解的地方。(4)
标签库描述符是一个xml文件,扩展名为tld。主要是用来配置标签的相关信息。
要注意的是,该文件必须放置在WEB-INF目录下,不能放置在WEB-INF/classes或者WEB-INF/lib目录下
下面我们来分析怎么来写这个标签库描述符。
整个标签库描述符的根元素是<taglib>也就是说所有的有关内容都要写在<taglib>和</taglib>内。它包含13个子元素。
1、<description>该标签为标签库提供一个文本的描述。
2、<display-name>为标签库提供一个简短的指定的名称。
3、<small-icon>为标签库指定一个小图标。16X16大小。
4、<large-icon>为标签库指定一个大图标。32X32大小。
5、<tlib-version>指定标签库的版本。
6、<short-name>为标签库指定一个简单的默认的名字。
7、<uri>第一个公开的URI,用来唯一的标识这个标签库。
8、<validator>用于提供验证的。它含有三个子元素。后面会分析到。
9、<listener>用于为标签提供一个监听器。他有4个子元素。
10、<tag>用于指定自定义标签的相关信息。他又12个子元素。

11、<tag-file>用于指定标签文件的相关信息。他又7个子元素。

12、<function>用于指定在表达是语言中使用的函数,他又8个子元素。
13、<taglib-extension>它包含一个或多个<extension-element>元素,用于提供这个标签的扩展信息。
下面我们来看一些元素的子元素。
<validator>
1)<description>为验证器提供一个文本描述。
2)<validator>指定标签库的验证类。验证类必须是javax.servlet.jsp.tagext.TagLibraryValitor类的子类。
3)<init-param>用于指定验证类的初始化参数。他有三个子元素。
              <description>为初始化参数提供一个文本描述。
              <param-name>指定初始化参数的名字。
              <param-value>指定初始化参数的值。
<listener>
1)<description>为监听器提供一个文本描述。
2)<display-name>为监听器制订一个简短的名字。
3)<icon>用于为监听器指定大小图标。他有两个子元素
              <small-icon>指定小图标。
              <large-icon>指定大图标。
4)<listener-class>指定监听器类的路径。(完整限定名)javax.servlet和javax.server.http包中提供监听器类。
<tag>
1)<description>为自定义标签提供一个文本描述。
2)<display-name>为标签指定一个简短的名字。(用于某些工具作提示用)
3)<icon>为标签指定大小图标。他有两个子元素
              <small-icon>指定小图标。
              <large-icon>指定大图标。
4)<name>指定自定义标签的名称。用于在JSP页面中被引用
5)<tag-class>指定标签处理器类的完整限定名。(包.类名)

6)<body-content>指定标签体的格式。可以取4个值。

              empty表示标签没有标签体。 相当于<input>标签。

              JSP表示标签体中可以包含JSP代码;

              scriptless表示标前体中可以包含EL表达式和JSP的动作元素。但是不能包含JSP的脚本元素。比如scriptlet代码。

              tagdependent表示标签体内的内容交给标签本身来处理,也就是说,我们在标签体内写了任何的东西,都交给标签处理程序来处理。而不再是结果了。

7)<variable>
定义标签处理器提供给JSP页面的脚本变量,由6个子元素。
              <description>为变量提供文本描述
              <name-given>直接给出变量的名称。
              <name-from-attribute>表示自定义标签的某个属性值作为变量的名称。
              <variable-class>指定变量所属类型。默认为java.lang.String.
              <declare>指定变量是否申明。默认为true.
              <scope>指定变量的范围。可能取值有3种。
                     AT_BEGIN表示变量的范围从开始标签到JSP页面结束。
                     NESTED表示变量的范围从开始标签到结束标签之间。
                     AT_END表示变量的范围从结束标签到JSP页面结束。
8)<attribute>用于设定标签的属性,他又6个子元素。
              <description>为该属性指定一个文本描述。
              <name>指定属性的名称。
              <requried>指定属性是否是必须的。默认是false.
              <rtexprvalue>指定该属性是否是一个运行时的属性类型。
              <type>指定属性的类型。
              <fragement>指定属性是否是JspFragment对象。默认为false;
9)<dynamic-attribute>指定标签是否支持动态属性。
10)<example>提供一个使用该标签例子的信息描述。
11)<tag-extension>包含一个或者多个<extension-element>元素,用于提供这个标签的扩展信息。
12)<tei-class>这个标签指定javax.servlet.jsp.tagext.TagExtraInfo的子类。
 

<tag-file>
1)<description>提供标签文件的一个描述。
2)<display-name>为标签文件指定一个简短的名字。
3)<icon>用于为标签文件指定大小图标。他有两个子元素
              <small-icon>指定小图标。
              <large-icon>指定大图标。
4)<name>指定标签文件的名称。
5)<path>指定标签文件的路径。
6)<example>提供一个使用该标签例子的信息描述。
7)<tag-extension>包含一个或者多个<extension-element>元素,用于提供这个标签的扩展信息。
<function>
1)<descrition>为EL函数提供一个描述
2)<display-name>为EL函数指定一个简短的名字。
3) 为EL函数指定大小图标。他有两个子元素
              <small-icon>指定小图标。
              <large-icon>指定大图标。
4)<name>为EL函数指定名称。
5)<function-class>指定实现了该函数的java类的名称。
6)<function-signture>指定El函数的原型。
7)<example>提供一个使用该函数例子的信息描述。
8)<function-extension>包含一个或者多个<extension-element>用于提供这个函数的额外信息。
 

三、好了,到目前为止我们就完成了整个的前期工作,下面我们只要在Jsp页面内创建我们的自定义标签就好了。
使用taglib的指令来引入标签描述符,并且使用prefix的属性来给自己的标签器一个名字。
<%@ taglib uri="WEB-INF/welcome.tld" prefix="w" %>
 

 

四、但是这地方要注意的事,我们也可以把我们的标签描述符直接的描述在我们的web.xml中,也就是在我们的web程序描述文件里,加入我们的标签描述符。就在web.xml中加入

<jsp-config>
<taglib>
       <taglib-uri>/mytag</taglib-uri>
       <taglib-location>/WEB-INF/welcome.tld</taglib-location>
</taglib>
</jsp-config>
这样的元素来表示可以用/mytag这样的uri来找到对应于/WEB-INF/下的welcome.tld文件。所以我们在jsp页面内引入标签描述符的时候,可以改成
<%@ taglib uri=”/mytag" prefix="w" %>
 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息