如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。
用tags定义脚本变量
tag处理类
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。
对象的生存周期(scope)如下表:
对象的生存周期表
名字
可访问范围
生存周期
page
当前页面
一直有效,除非页面向客户提交响应或重定向到一个新页面
request
当前页面或当前页面重定向到的页面
一直有效,除非页面向客户提交响应
session
当前页面或在同一浏览器窗口中的页面
一直有效,除非关闭当前浏览器、超时、网络故障
application
整个web应用程序的所有请求
一直有效,除非发生网络故障、服务器故障
提供关于脚本变量的信息
以下示例定义了一个名为“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>
</font>
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息:
· 脚本变量名称
· 脚本变量所属的类
· 此脚本变量是否引用了一个新的或已存在的对象
· 此脚本变量的有效性
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。
Variable元素
Variable元素有如下子元素:
· name-given ?D?D 给出的名字,是一个常量
· name-from-attribute?D?D 属性名,在编译时给出的属性名
name-given或name-from-attribute两者必须选一,但以下子元素是可选的:
· variable-class?D?D变量的类型,缺省为java.lang.String。
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型:
脚本变量的有效范围
值
有效性
方法
NESTED
在tag标签的开始和结束之间
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用
AT_BEGIN
从tag标签的开始一直到页面结束
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用
AT_END
从tag标签的结束一直到页面结束
在doEndTag中调用
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素:
<tag>
<variable>
<name-from-attribute>id</name-from-attribute>
<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页面结束的范围内都可用的话,那它的范围应设为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的静态方法






