JSP中的自定义标签(摘录)

来源:互联网 发布:软件营销方案 编辑:程序博客网 时间:2024/04/30 11:13

定义标签

要定义一个标签,需要一下准备工作:

☆ 为标签开发一个标签处理累计帮助类

☆ 在标签库中声明标签描述符

标签处理器

标签处理器是由网络容器调用的,用来处理运行的包含标签的JSP页面。标签处理器必须实现Tag或BodyTag接口。这些接口可以携带Java对象并产生一个标签处理器。对新创建的处理器,你可以使用TagSupport及BodyTagSupport类作为基类,这些类基接口在javax.servlet.jsp.tagext包中。

有Tag及BodyTag接口定义的处理器方法由JSP页面的servlet任何时候调用。当遇到标签的起始处时,JSP页面的servlet调用方法来初始化处理器接着调用处理器的doStartTag方法,当遇到结束点时,处理器的方法doEndTag被调用。另外的一些方法在标签相互通信时使用。

标签处理器有API接口来与jsp页面通信。其API入口点是page context(javax.servlet.jsp.PageContext)。通过API,处理器可以返回其它隐含对象(request,session,application).

隐含对象有些属性,它们可以通过使用[set|get]方法来调用。

如果标签嵌套,标签处理器也要访问相应的标签。

标签库描述符

标签库描述符是XML格式的文档。TLD包含库的所有信息及库中的每个标签。TLD由Web容器使用来验证标签并由JSP页面开发工具来使用。

TLD文件必须以扩展名.tld为后缀。这类文件保存在WEB-INFO目录中或它的子目录中,当你使用部署工具将TLD加到WAR中时,它会自动的加入到WEB-INFO中。

TLD文件必须以下面的格式开头:

<?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>

J2EE SDK1.3版可以识别1.1,1.2版的DTD。然而由于本章文档使用的是1.2版,所以必须使用更新的标签库。Struts库遵循1.1版的DTD,其中有些元素的名称有些改变。

TLD的根元素是taglib,子元素列表如下:

Element

Description

tlib-version

The tag library’s version

Jsp-version

The JSP specification version that the tag library requires

Short-name

Optional name that could be used by a JSP page authoring tool to create names with a numeric value

Uri

A URI that uniquely identifies the tag library

Display-name

Optional name intended to be displayed by tools

Small-icon

Optional small icon that can be used by tools

Large-icon

Optional large icon that can be used by tools

Description

Optional tag-specific information

Listener

See listener Element

Tag

See tag Element

元素listener

标签库可以指定一些类——事件监听类。(参照处理servlet生命周期事件)。这些监听类都作为listener元素列于TLD中,网络容器将实例化监听类并通过与在WAR中定义的监听类类似的方法来注册。不像WAR级的监听类,,标签库中注册的监听类没有定义顺序。Listener元素的唯一子元素是listener-class,它必须包含监听类名的全称。

元素tag

库中的每个标签都有一个给定的名称及该标签的处理器来描述,标签创建的脚本变量信息,标签属性信息。脚本变量信息可以直接在TLD中给出或通过标签的额外信息获取。每一属性都包含说明是否需要该属性,它的值是否可以通过请求时表达式来决定,及其属性类型。

下表列出了标签的子元素信息:

Element

描述

Name

标签唯一名称

Tag-class

标签处理器类名

Tei-class

可选子类 javax.servlet.jsp.tagext.TagExtraInfo

Body-content

内容类型

Display-name

可选的用来显示的名字

Small-icon

可由工具使用的可选的 small-icon

Large-icon

可由工具使用的可选的large-icon

Description

可选的描述信息

variable

可选的脚本变量信息

attribute

标签属性信息

下面的部分描述了需要为每种类型标签开发的方法几TLD元素。

简单标签

标签处理器

简单标签处理器必须实现doStartTag及doEndTag两个标签接口的方法。方法doStartTag在开始遇到时被调用,并返回SKIP_BODY,因为标签没有体。方法doEndTag在标签结束时被调用,如果其它页面需要使用则返回EVAL_PAGE,否则返回SKIP_PAGE.

在第一部分提到的标签:<tt:simple />将由下面的标签处理器来实现:

public SimpleTag extends TagSupport {

public int doStartTag() throws JspException {

try{

pageContext.getOut().print(“hello.”);

}catch(Exception e) {throw new JspTagException(“SimpleTag:”+e.getMessage());}

return SKIP_BODY;

}

public int doEndTag() {

return EVAL_PAGE;

}

}

元素body-content

没有体的标签必须用body-content元素来声明体内容为空:

<body-content>empty</body-contnent>

标签属性

在标签处理器中定义属性

对于每一个标签属性,你必须在标签处理器中定义一个属性及get/set方法来遵循JavaBean的结构。例如,下面的处理器处理Struts logic:present tag.

<logic :present parameter=”Clear”>

包含下面的声明及方法:

protected String parameter=null;

public String getParameter() {

return (this.parameter);

}

public void setParameter(String parameter) {

this.parameter=parameter;

}

注意:如果属性命名为id,标签处理器继承了TagSupport类,你不需要定义该属性及set/get方法,因为已经由TagSupport定义了。

一个属性值类型为String的标签可以命名一隐含对象供标签处理器使用。隐含对象属性可以通过传递标签属性值到隐含对象的[get/set]Attribute方法来访问。这是一个好方法来传递脚本变量到标签处理器。

元素attribute

对于每一个标签属性,你必须指定该属性是否必须,该标签的知是否可以通过表达式确定,属性类型在元素attribute中。对于静态类型数值通常为java.lang.String。如果元素rtexprvalue是true或者是yes,元素类型决定了返回值类型。

<attribute>

<name>attr1</name>

<required>true|false|yes|no</required>

<rtexprvalue>true|false|yes|no</rtexprvalue>

<type>fully_qualified_type</type>

<attribute>

如果属性不必须,标签处理器应该指定一个默认值。

标签元素logic:present声明了一个属性parameter不必须,且它的值可以有一个表达式来赋值。

<tag>

<name>present</name>

<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class>

<body-content>JSP</body-content>

……

<attribute>

<name>parameter</name>

<required>false</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

……

</tag>

属性验证

标签库的文档应该为标签属性描述合法的值。当JSP页面被运行时,网络容器将加强在TLD元素中的每一个属性的制约。

传递到标签的属性也可以在传递时间由一个继承于TagExtraInfo的类的方法isValid来验证。该类也用来提供标签定义的脚本变量的信息。

方法isValid传递对象TagData的属性信息,该对象包含了标签每一属性的属性值。由于验证过程在传输期间进行,所以属性值在请求时开始计算并送到TagData.REQUEST_TIME_VALUE.

标签<tt:twa attr1=”value1” />有下面的TLD属性元素:

<attribute>

<name>attr1</name>

<required>true</required>

<rtexprvalue>true</a>

</attribute>

该声明显示attr1的止可以在运行时决定。下面的方法isValid检查attr1的值是合法的Boolean值。注意,由于attr1的治可以在运行时计算,所以isValid必须检查标签的使用者是否提供了运行时值。

Public class TwaTEI extends TagExtraInfo {

Public boolean isValid(Tagdata data) {

Object o=data.getAttribute(“attr1”);

If(o!=null&& o!=TagData.REQUEST_TIME_VALUE) {

o.toLowerCase().equals(“true”)||o.toLowerCase().equals(“false”))

return true;

else

return false;

}

else

return true;

}

}

标签体

标签处理器

标签处理器在处理还标签体的标签时实现有所不同,主要取决于处理器是否需要与体交互。如果交互则标签处理器读取或修改体的内容。

标签处理器不与体交互

如果处理器不与体交互,标签处理器需要实现Tag接口(或继承TagSupport)。如果标签的体需要计算,方法doStartTag需要返回EVAL_BODY_INCLUDE;否则,则返回SKIP_BODY.

如果标签处理器需要重复计算体,则该标签需要实现接口IterationTag或者继承TagSupport。如果标签决定体需要再计算一次则从doStartTag和doAfterBody返回EVAL_BODY_AGAIN。

标签处理器与体交互

如果标签处理器需要与体交互,标签处理器必须实现BodyTag,这样的处理器实现了方法doInitBody,doAfterBody。这些方法与传递到标签处理器的体内容交互。

体内容支持一些方法来读写它的内容。标签处理器可以使用体内容的getString/getReader方法从体中获取信息,并通过writeOut方法来将体内容写到输出流。写提供writeOut方法,该方法可以通过使用标签处理器的方法getPreviousOut来获取。该方法确保标签处理器的结果对封闭的标签处理器可行。

如果标签的体需要计算,方法doStartTag需要返回EVAL_BODY_BUFFERED,否则,返回SKIP_BODY。

方法doInitBody

该方法在体内容设置之前求值之后被调用。通常使用该方法初始化体内容。

方法doAfterBody

该方法在体内容求值之后被调用。像方法doStartTag一样,doAfterBody方法必须返回指示是否继续计算体。这样,如果体需要再计算一次,就像实现了迭代标签一样,doAfterBody方法应返回EVAL_BODY_BUFFERED,否则返回SKIP_BODY.

方法release

标签处理器应该重新设置它的状态并通过方法release释放任何私有资源。

下面的例子从体中读取内容并传递到一个执行查询的对象。由于体不需要重复计算,所以doAfterBody返回SKIP_BODY。

Public class QueryTag extend BodyTagSupport

{

public int doAfterBody() throws JspTagException

{

BodyContent bc =getBodyContent();

String query=bc.getString();

Bc.clearBody();

Try

{

Statement stm=connection.createStatement();

Result=stm.executeQuery(query);

}catch(SQLException e){ throw new JspTagException(“QueryTag:”+e.getMessage());}

return SKIP_BODY;

}

}

元素body-content

对于有体的标签,必须用下面的方法指定体内容的类型:

<body-content>JSP|tagdependent</body-content>

体内容包含自定义及核心标签,脚本元素,HTML文本都统一为JSP。这就是为Struts描述的logic:present标签。其它类型体内容,例如,SQL 语句传递查询标签,将会标以tagdependent.

注意,body-content元素的值不会影响体处理器的解释。

定义脚本变量的标签

标签处理器

标签处理器通过页面上下文设置的脚本变量负责创建、设置一个对象引用。它通过使用pageContext.setAttribute(name,value,scope)或pageContext.getAttribute(name,value)方法来实现。典型的,属性传递到自定义标签指定的脚本变量对象名;该对象可以通过调用属性的get方法返回。

如果脚本变量的值依赖于标签处理器上下文的一个对象。可以通过使用pageContext.getAttribute(name,scope)方法返回。

一般过程是标签处理器返回脚本变量,对对象进行处理,接着使用pageContext.setAttribute(name,object)方法给变量赋值。

对象受作用域总结如下表,作用于限制了对象的可访问性及对象的生命周期。

Name

Accessible From

Lifetime

Page

Current page

Until the response has been sent back to the user or the request is passed to a new page

Request

Current page and any included or forwarded pages

Until the response has been sent back to the user

Session

Current request and any subsequent request from the same browser

The file of the user’s session

Application

Current and any future request from the same Web application

The life of the application

提供脚本变量的信息

在标签定义脚本变量的例子中,定义了一个脚本变量book用来访问book信息。

<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails”/>

<font color=”red” size=”+2”>

<%=messages.getString(“CartRemoved”)%>

<strong><jsp:getProperty name=”book” property=”title”/></strong>

<br>&nbsp;<br>

</font>

当JSP页面包含该标签并转换时,网络容器产生代码以与脚本变量保持同不。要产生代码,网络容器需要脚本变量的一些信息:

☆ 变量名

☆ 变量类

☆ 该变量是否引用一个新的或存在的对象

☆ 该变量可访问

有两种方法可以提供这些信息:指定变量TLD子元素或定义标签的额外的信息类并在TLD中包含tei-class元素。使用变量元素很方便,但是不够灵活。

元素variable

元素variable有下面的一些子元素:

name-given:变量名作为一个常量

name-from-attribute:属性名,它的解释时间将传给变量名。

上面两者之一是必需的,下面的子元素是可选的:

variable-class:该变量的全名,缺省类型为java.lang.String.

declare:该变量是否引用一个新对象。缺省值为True.

scope:脚本变量的作用范围。

下表描述了变量的可用性及变量必须设置的方法

Value

Availability

Method

NESTED

Between the start tag and the end tag

In doInitBody Tag;otherwise,in doStartTag

AT_BEGIN

From the start tag until the end of the page

In doInitBody ,doAfterBody,and doEndTag for a tag handler implementing BodyTag,otherwise,in doStartTag and doEndTag

AT_END

After the end tag until the end of the page

In doEndTag

类TagExtraInfo

你可以通过扩展类javax.servlet.jsp.TagExtraInfo来定义一个额外标签信息类。TagExtraInfo必须实现方法getVariableInfo来返回一个VariableInfo对象数组,包含下面的一些信息:

☆ 变量名

☆ 变量类

☆ 该变量是否引用一个新对象

☆ 该变量的可访问性

网络容器传递一个名为data的参数到方法getVariableInfo,这些属性用来提供对象VariableInfo。

Struts标签库提供了由bean:define创建的在标签额外信息类DefineTei中的脚本变量信息。由于脚本变量的名称及类作为标签的属性来传递,可以使用方法data.getAttributeString来返回,并填充构造函数VariableInfo。为了脚本变量book能在页面的余下部分使用,book的域应该设置为AT_BEGIN.

       Public class DefineTei extends TagExtraInfo {

              Public VariableInfo[] getVariableInfo(TagData data) {

              String type=data.getAttributeString(“type”);

                     If(type==null)

                            Type=”java.lang.Object”;

                     Return new VariableInfo[] {

                     New VariableInfo(data.getAttributeString(“id”),,type,true,VariableInfo.AT_BEGIN

              };

       }

}

为脚本变量定义的标签额外信息类必须在TLD中声明,这样元素tei-class将会如下:

<tei-class>org.apache.struts.taglib.bean.DefineTagTei</tei-class>

与标签协作

通过共享对象实现标签的协作JSP技术支持两种类型的对象共享。第一种类型需要共享对象命名、存储在page context中。为了让其它标签访问,标签处理器使用pageContext.getAttribute(name,scope)方法。

第二种方法是由封闭的标签处理器创建的对象对内部的标签处理器是可访问的。这种形式的对象共享有个优点,它使用了对象私有的名字空间,这样减少了潜在的命名冲突。

为访问闭合标签创建的对象,标签处理器必须首先通过静态方法TagSupport.findAncestorWithClass(from,class)或TagSupport.getParent方法获得封闭标签。前一个方法应该在特定的嵌套的标签处理器不能保证时使用。一旦ancestor返回,标签处理器就能访问任何静态或动态创建的对象。静态创建的对象是父类的成员。私有对象也可以动态的创建。这样的对象可以通过方法setValue存储在标签处理器中,可以通过getValue方法返回。

下面的例子展示了一个标签处理器支持命名及私有对象访问共享对象的例子。在该例子中,,处理器为查询标签检验一个名称为connection的属性是否以设置到方法doStartTag中。如果connection属性已经设置,处理器将从page context对象返回connection对象,否则,标签处理器先返回封闭标签的处理器然后从处理器返回connection对象。

Public class QueryTag extends BodyTagSupport {

       Private String connectionId;

       Public int doStartTag() throws JspException {

              String cid=getConnection();

              If(cid!=null){

                     Connection=(Connection)pageContext.getAttribute(cid);

                     }

                     else

                            connectionTag ancestorTag=(ConnectionTag)findAncestorWithClass(this,

                     ConnectionTag.class);

                     If(ancestorTag==null) {

                            Throw new JspTagException(“A quety without a connection attribute must be nested within a connection tag.”);

                     Connection =ancestorTag.getConnection();

              }

       }

}

由标签处理器实现的查询标签可以在下面的方法中使用:

<tt:connection id=”con01” …..>…..</tt:connection>

<tt:query id=”balances” connection=”con01”>

       SLECT account,balance FROM acct_table

                     Where customer_number =<%=request.getCustno()%>

</tt:query>

<tt:connection …>

       <x:query id=”balances”>

              SELECT account,balance FROM acct_table

                            Where customer_number=<%=request.getCustno()%>

       </x:query>

</tt:conncetion>

在TLD中必须指出属性connection是可选的:

<tag>

       …

       <attribute>

              <name>connection</name>

              <required>false</required>

       </attribute>

</tag>

例子

自定义标签展示了在开发JSP应用中两种常见问题的解决方案:最小化在JSP页面中的编码量及确保良好的表现形式。为了达到这样的目的,在本章的前面几节展示了各类标签。

迭代标签

构造动态页面内容经常需要使用流控制语句。流控制标签可以减少这类语句的数量。

Struts的logic:iterate标签返回一个存储在JavaBean组建中的对象。并把它赋值给脚本变量。从脚本变量种返回的标签体信息

JSP页面

两个Duke’s应用页面,catalog.jsp和showcart.jsp.使用了logic:iterate标签来列出collection中的对象。下面展示了catalog.jsp的一段引用,这个JSP页面初始化了iterate标签,该标签设置了脚本变量book,代码片断如下:

<logic:iterate name=”bookDB” property=”books” id=”book” type=”database.BookDetails”>

       <bean:define id=”bookId” name=”book” property=”bookId” type=”java.lang.String”/>

       <tr>

       <td bgcolor=”#ffffaa”>

       <a href=”<%=requet.getContextPath()%>/bookdetails?bookId=<%=bookId%>”>

       property=”title”/>&nbsp;</strong></a></td>

       <td bgcolor=”#ffffaa” rowspan=2>

       <jsp:setProperty name=”currency” property=”amount” value=”<%=book.getPrice()%>”/>

       <jsp:getProperty name=”currency” property=”format”/>&nbsp;</td>

       <td bgcolor=”#ffffaa” rowspan=2>

       <a href=”<%=request.getContextPath()%>/catalog?Add=<%=bookId%>”>&nbsp;</a></td></tr>

       <tr>

       <td bgcolor=”#ffffff”>

       &nbsp;&nbsp;<%=messages.getString(“By”)%><em>

       <jsp:getProperty name=”book” property=”firstName”/>&nbsp;

       <jsp:getProperty name=”book” property=”surname”/></em></td></tr>

</logic:iterate>

标签处理器

标签logic:iterate的实现遵循JSP1.1规范,JSP1.2规范增加了一些新特性。下面将进行讨论:

标签logic:iterate支持几种方法来初始化collection:作为标签属性或者是作为bean或bean的属性。

标签额外信息类

在IterateTei标签的额外信息类中提供了脚本变量的信息。脚本变量的名称及类传递到构造器VariableInfo。

       Public class InterateTei extends TagExtraInfo {

              Public VariableInfo[] getVariableInfo(TagaData data) {

              String type =data.getAttributeString(“type”);

              If(type==null)

                     Type=”java.lang.Object”;

                     Return new VariableInfo[] {

                            New VariableInfo(data.getAttributeString(“id”),type,true,VariableInfo.AT_BEGIN)

                     };

              }

       }

模板标签库

模板提供了一种方法分离一般元素的方法。把所有的元素放到文件中使得易于维护且看起来很棒的方法。这样也使得个人开发变得容易,因为设计者可以专注于表现部分。

模板是JSP页面中每屏都需要变动的部分,每部分都作为一个参数来引用模板。例如,一个简单的模板能包容顶部的标题参数及体参数。

模板使用了一个嵌套的标签。

JSP页面

在Duke’s Bookstore例子中使用的模板template.jsp如下,该页面包括了创建一个产生屏定义并使用insert标签插入参数的JSP页面。

<%@ taglib uri=”/tutorial-template.tld” prefix=”tt” %>

<%@ page errorPage=”errorpage.jsp”%>

<%@ include file=”screendefinitions.jsp” %>

<html>

<head>

       <title>

              <tt:insert definition=”bookstore” parameter=”title”/>

       </title>

</head>

<tt:insert definition=”bookstore” parameter=”banner”/>

<tt:insert difinition=”bookstore” parameter=”body”/>

       </body>

</html>

页面screendefinitions.jsp创建了一个基于请求属性的页面定义

<tt:definition name=”bookstore” screen=”<%=(String)request.getAttribute(“/”selectedScreen/”)%>”>

<tt:screen id=”/enter”>

       <tt:parameter name=”title” value=”Duke’s Bookstore” direct=”true”/>

       <tt:parameter name=”banner.jsp” direct=”false”/>

       <tt:parameter name=”body” value=”/bookstore.jsp” direct=”false”/>

</tt:screen>

<tt:screen id =”/catalog”>

       <tt:parameter name=”title” value=”<%=messages.getString(“TitleBookCatalog”)%>” direct=”true”/>

</tt:definition>

模板由Dispatcher servlet实例化,Dispatcher首先获得请求页面并将它作为一个请求属性存储起来。这是必需的,因为当请求定向到template.jsp时,请求URL不包含原始请求板反映了定向路径,最后servlet将请求重定向到template.jsp

public class Dispatcher extends HttpServlet{

       public void doGet(HttpServletRequest request,HttpServletResponse response){

              request.setAttribute(“selsectedScreen”,request.getServletPath());

              RequestDispatcher dispatcher=request.getRequestDispatcher(“/template.jsp”);

              If(dispatcher!=null)

              Dispatcher.forward(request.response);

       }

       public void doPost(HttpServletrequest request,HttpServletResponse response) {

              request.setAttribute”selectedScreen”,request.getServletPath());

              RequestDispatcher dispatcher=request.getRequestDispatcher(“/template.jsp”);

              If(dispatcher!=null)

                     Dispatcher.forward(rquest,response);

              }

       }

标签处理器

模板标签库包含四个标签处理器——DefinitionTag,ScreenTag,ParameterTag,InsertTag,DefinitionTag,ScreenTag,ParameterTag组成了一系列嵌套的标签处理器,他们可以共享共有的及私有的对象。DefinitionTag创建了一个共有的对象definition供InsertTag使用。

Public int doStartTag() {

       HashMap screens=null;

       Screens=(HashMap)pagecontext.getAttribute(“screens”,pageContext.APPLICATION_SCOPE);

       If(screens==null)

              PageContext.setAttribute(“screens”,new HashMap(),pageContext.APPLICATION_SCOPE);

       Return EVAL_BODY_INCLUDE;

}

下面的表格是关于Duke’s Bookstore应用的哈西表

Screen Id

Title

Banner

Body

/enter

Duke’s bookstore

/banner.jsp

/bookstore.jsp

/catalog

Book catalog

/banner.jsp

/catalog.jsp

/bookdetails

Book description

/banner

/bookdetails.jsp

/showcart

Your shopping cart

/banner.jsp

/showcart.jsp

/cashier

Cashier

/banner.jsp

/cashier.jsp

/receipt

Receipt

/banner.jsp

/receipt..jsp

 

在doEndTag中,DefinitionTag创建了一个公有的对象Definition:

public int doEndTag() throws JspTagException {

       try {

              Definition definition=new Definition();

              Hashtable screens=null;

              ArrayList params=null;

              TagSupport screen=null;

              Screens=(HashMap)pageContext.getAttribute(“screens”,pageContext.APPLICATION_SCOPE);

       If(screens!=null)

              Params=(ArrayList)screens.get(screenId);

              Else

                     ……

       if(params==null)

                     ……

       Iterator ir=null;

       If(params!=null)

              Ir=params.iterator();

       While((ir!=null)&&ir.hasNext())

              Definition.setParam((Parameter) ir.next());

              //put the difinition in the page context.

              PageContext.setAttribute(

                     DefinitionName,definition);

              }catch(Exception ex) {

                     ex.printStackTrace();

              }

              return EVAL_PAGE;

       }

如果传递给请求的URL是/enter,Definition包含下面的一些项:

Title

Banner

Body

Duke’s bookstore

/banner.jsp

/bookstore.jsp

URL/enter的定义如下表

Parameter name

Parameter value

IsDirect

Title

/banner.jsp

True

Banner

/banner.jsp

False

Body

/bookstore.jsp

false

InsertTag使用Definition插入一个参数到响应中。在方法doStartTag中,它从page context返回对象definition.

Public int doStartTag()

{

       //get the definition from the page context

       definition =(Definition) pageContext.getAttribute(definitionName);

       //get the parameter

       if(parameterName!=null)&&definition!=null)

              parameter=(Parameter)definition.getParam(parameterName);

       if(parameter!=null)

              directInclude=parameter.isDirect();

       return SKIP_BODY;

}

方法doEndTag插入了一个参数值,如果该参数是直接参数,它将直接传到响应对象,否则请求将送到该参数,且响应对象动态的包含到所有的响应中。

       Public int doTndTag() throws JspTagException {

              Try{

                     If(directInclude&&parameter!=null)

                            PageContext.getOut().print(parameter.getValue());

                     Else{

                           

                            If((parameter!=null)&&(parameter..getValue()!=null))

                                   PageContext..include(parameter.getValue());

                            }                  

}catch(Exception e){

       throw new JspTagException(e.getMessage());

}

return EVAL_PAGE;

}

标签处理器是如何被调用的?

标签接口定义了位于标签处理器和JSP页面servlet之间的基础协议。它定义了在遇到标签起始及结束处是要调用的方法。

JSP servlet调用setPageContext,setParent及在调用doStartTag方法之前调用属性设置方法。JSP servlet也负责在结束页面之前调用release以释放资源。

下面是一个典型的标签处理器方法调用顺序的例子:

ATag t =new Atag();

t.setPageContext(…);

t.setParent(…);

t.setAttribute(value1);

t.setAttribute2(value2)

t.doStartTag();

t.doEndTag();

t.release();

接口BodyTag扩展自Tag,它允许标签处理器访问body。该接口提供了三个新方法:

       .setBodyContent

       .doInitBody

       .doAfterBody

一个典型的调用顺序如下:

t.doStartTag();

out=pageContext.pushBody();

t.setBodyContent(out);

//perform any initialization needed after body content is set

t.doInitBody();

t.doAfterBody();

//while doAfterBody returns EVAL_BODY_BUFFERED we iterate body evaluation

……

t.doAfterBody();

t.doEndTag();

t.pageContext.popBody();

t.release();                           

<script language="javascript" src="http://www.leftworld.net/stat/stat.php?user=&amp;style=null&amp;referer=http%3A//www.baidu.com/s%3Flm%3D0%26si%3D%26rn%3D10%26ie%3Dgb2312%26ct%3D0%26wd%3DJSP+%25D6%25D0%25B5%25C4%25D7%25D4%25B6%25A8%25D2%25E5%25B1%25EA%25C7%25A9%26pn%3D10%26cl%3D3" type="text/javascript"></script>