<variable-class>database.BookDetails</variable-class>
<declare>true</declare>
<scope>AT_BEGIN</scope>
</variable>
</tag>
额外tag信息类
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息:
? 变量名
? 变量所属类名
? 此变量是否引用了一个新对象
? 此变量的有效范围
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。
以struts 为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用 data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,
http://www.kpwang.com/那它的范围应设为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)};}}
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下:
<tei-class>
org.apache.struts.taglib.bean.DefineTagTei
</tei-class>
具有协作关系的tag
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为 connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。
public class QueryTag extends BodyTagSupport{private String connectionId;public int doStartTag() throws JspException{String cid = getConnection();if(cid != null){//存在一个connection id,使用它。connection = (Connection) pageContext.getAttribute(cid);}else{ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, ConnectionTag.class);if(ancestorTag == null){throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”);}connection = ancestorTag.getConnection();}}}
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种:
<tt:connection id=”con01” ...> ... </tt:connection>
<tt:query id=”balances” connection=”con01” >
SELECT account, balance FROM acct_table
where customer_num = <%= request.getCustno() %>
</tt:query>
或
<tt:connection ...>
<x:query id=”balances”>
SELECT account, balance FROM acct_table
where customer_num = <%= request.getCustno() %>
</x:query>
</tt:connection>
与此同时,在TLD中必须指定connection属性为可选的,定义如下:
<tag>
...
<attribute>
<name>connection</name>
<required>false</required>
</attribute>
</tag>
<declare>true</declare>
<scope>AT_BEGIN</scope>
</variable>
</tag>
额外tag信息类
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息:
? 变量名
? 变量所属类名
? 此变量是否引用了一个新对象
? 此变量的有效范围
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。
以struts 为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用 data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,
http://www.kpwang.com/那它的范围应设为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)};}}
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下:
<tei-class>
org.apache.struts.taglib.bean.DefineTagTei
</tei-class>
具有协作关系的tag
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为 connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。
public class QueryTag extends BodyTagSupport{private String connectionId;public int doStartTag() throws JspException{String cid = getConnection();if(cid != null){//存在一个connection id,使用它。connection = (Connection) pageContext.getAttribute(cid);}else{ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, ConnectionTag.class);if(ancestorTag == null){throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”);}connection = ancestorTag.getConnection();}}}
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种:
<tt:connection id=”con01” ...> ... </tt:connection>
<tt:query id=”balances” connection=”con01” >
SELECT account, balance FROM acct_table
where customer_num = <%= request.getCustno() %>
</tt:query>
或
<tt:connection ...>
<x:query id=”balances”>
SELECT account, balance FROM acct_table
where customer_num = <%= request.getCustno() %>
</x:query>
</tt:connection>
与此同时,在TLD中必须指定connection属性为可选的,定义如下:
<tag>
...
<attribute>
<name>connection</name>
<required>false</required>
</attribute>
</tag>