第 3 步:在标签处理程序 Java 类中创建属性
我们希望为 mapDefine
标签指定三个属性,如下所示:
属性说明
id |
新 scriptlet 变量的名字。 |
scope |
新 scriptlet 变量所在的范围。 |
type |
新 scriptlet 变量的类型 (HashMap 、FastHashMap 、TreeMap 或者 FastTreeMap )。 如果 type 设置为 hash ,那么就会创建一个 HashMap 。如果 type 设置为 fasthash ,那么将创建 FastHashMap 。 |
在 JSP 页中使用这个标签时,它看起来将像下面这样:
<map:mapdefine type="hash" scope="session" id="editParams"> ... </map:mapdefine>
这个标签将在会话范围内创建一个名为 editParams
的 HashMap
。
为了在标签处理程序中创建属性,需要定义相应的 JavaBean 属性。 因此,每一个属性在标签处理程序中都有对应的 setter 方法,如下所示:
public class MapDefineTag extends TagSupport { ... private String type = FASTTREE; private String id; private String scope; public void setType(String string) { type = string; } public void setId(String string) { id = string; } public void setScope(String string) { scope = string; }
转换引擎将用硬编码的配置数据或者运行时表达式设置这个标签的属性。 我们将在 第 4 步:在 TLD 文件中定义属性 中对此做更详细的讨论。
在 第 5 步:实现 doStartTag() 方法 中,我们将在标签处理程序的 doStartTag()
方法中使用这些属性。
第 4 步:在 TLD 文件中定义属性
就 像上一小节中所做的那样,通过声明 JavaBean 属性定义自定义属性,然后在 TLD 文件中声明这些属性。 每一个 JavaBean 属性都必须与相应的自定义标签属性相匹配。 在 TLD 中定义的属性必须匹配 JavaBean 属性,不过却可以有与标签属性不匹配的 JavaBean 属性。
下面是 MapDefineTag
的属性声明:
<tag> <name>mapDefine</name> <tag-class>trivera.tags.map.MapDefineTag</tag-class> <body-content>JSP</body-content> ... <attribute> <name>id</name> <required>true</required> <rtexprvalue>false</rtexprvalue> <description>The id attribute</description> </attribute> <attribute> <name>scope</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description>The scope attribute</description> </attribute> <attribute> <name>type</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description> Specifies the type of map valid values are fasttree, fasthash, hash, tree </description> </attribute> </tag>
name
元素指定属性的名字。required
元素指定属性是否是必需的(默认值是 false
)。rtexprvalue
元素表明属性是硬编码了转换时的值还是允许使用运行时 scriptlet 表达式。
记住,MapDefineTag
类必须为前面描述的每一个属性定义一个 JavaBean 属性,我们在 第 3 步:在标签处理程序 Java 类中创建属性 中完成这个任务。
第 5 步:实现 doStartTag() 方法
标签开始时调用 doStartTag()
方法 —— 从开发人员的角度看,这是当引擎遇到 <map:mapdefine></map:mapdefine>
时发生的。如果 doStartTag()
返回 SKIP_BODY
,那么将不处理标签正文。 如果它返回一个 EVAL_BODY_INCLUDE
,那么将处理正文。
MapDefine
类的 doStartTag()
方法完成以下工作:
- 根据
type
属性确定要创建的 map 的属性。
- 根据
scope
属性确定新的 map 对象放在什么范围内。
- 根据
id
属性确定新 map 对象要放入的范围的名字。
让我们更详细地分析这个过程。MapDefine
类检查 type
属性是设置为 FASTTREE
、HASH
、TREE
还是 FASTHASH
。然后创建相应的 map,如下所示:
/* String constants for the different types of maps we support */ public static final String FASTHASH = "FASTHASH"; public static final String FASTTREE = "FASTTREE"; public static final String HASH = "HASH"; public static final String TREE = "TREE"; /** The map we are going to create */ private Map map = null; /** The member variable that holds the type attribute */ private String type = FASTTREE; ... public int doStartTag() throws JspException { /** Based on the type attribute, determines which type of Map to create */ if (type.equalsIgnoreCase(FASTTREE)) { map = new FastTreeMap(); } else if (type.equalsIgnoreCase(HASH)) { map = new HashMap(); } else if (type.equalsIgnoreCase(TREE)) { map = new TreeMap(); } else if (type.equalsIgnoreCase(FASTHASH)) { map = new FastHashMap(); }
然后,用 id
和 scope
属性将 hashmap 以一个给定的名字设置到一个给定范围中:
private String id; private String scope; public int doStartTag() throws JspException { ... if (scope == null){ pageContext.setAttribute(id, map); }else if("page".equalsIgnoreCase(scope)){ pageContext.setAttribute(id, map); }else if("request".equalsIgnoreCase(scope)){ pageContext.getRequest().setAttribute(id, map); }else if("session".equalsIgnoreCase(scope)){ pageContext.getSession().setAttribute(id, map); }else if("application".equalsIgnoreCase(scope)){ pageContext.getServletContext().setAttribute(id, map); } return EVAL_BODY_INCLUDE; }
如果范围属性是 null
,那么 map 将放入页范围。否则,参数将放入通过 scope
属性传递的范围名所对应的范围中。
到目前为止,我们已经有一个非常简单的标签,它有三个属性:id
、scope
和 type
。 我们将用给定的名字将 map 放到一个范围中。但是,我们还有一件事没做,就是声明 scriptlet 变量。 为了做到这一点,需要向 TLD 再添加一项,这就是我们在下一小节中所要做的事。
第 6 步:声明 scriptlet 变量
要 理解 scriptlet 变量,必须理解 TLD 文件的作用。这个文件基本上是元数据的一个储存库,当 JSP 页转换为 servlet 时,标签会使用这些元数据。 在生成的 servlet 中,scriptlet 变量成了本地变量。 要让 JSP 转换引擎知道这些变量应当声明的类型,需要像下面这样在 TLD 文件中增加项:
<variable> <name-from-attribute>id</name-from-attribute> <variable-class>java.util.Map</variable-class> <scope>AT_BEGIN</scope> </variable>
将上面的代码片断放在 TLD 文件中 body-content
元素之后、attribute
元素之前。 在 variable
元素下面,我们声明了三个子元素:name-from-attribute
、variable-class
和 scope
。 name-from-attribute
指定 id
属性的值是转换引擎将要定义的 scriptlet 变量的名字。variable-class
是转换将要定义的变量的类类型。scope
指定变量什么时候可用:它可以嵌套到标签的正文中 (NESTED
)、在标签结束后 (AT_END
)、或者在标签的开始时 (AT_BEGIN
)。我们使用 AT_BEGIN
这一范围,它意味着变量的范围将是从标签的开始到当前 JSP 页的结束。
现在了解了如何构建简单自定义标签。在下一小节中,我们将分析标签的生存周期方法,以了解 JSP 页实际运行时所发生的情况。
分享到:
相关推荐
JSP自定义标签JSP自定义标签JSP自定义标签JSP自定义标签JSP自定义标签JSP自定义标签
jsp自定义标签jsp自定义标签jsp自定义标签
本人自行研究JSP自定义标签的学习笔记 目录如下: 目录 一、概述 1 1.1 使用简单标签机制 2 1.2 使用标签文件 3 二 、自定义标签简介 3 2.1 自定义标签概念 3 2.2 标签相关概念 3 2.3 如何创建自定义标签 3 三、自...
jsp自定义标签jsp自定义标签jsp自定义标签jsp自定义标签
jsp 自定义标签 一个简单的自定义标签实现
使用jsp自定义标签的功能实现权限的控制。(如果用户没有某个模块的删除权限,就不现实这个删除按钮) 在整个项目中所有的页面都可以引入自定义的标签去做到权限的控制。 自定义标签文件 删除 可以控制页面中的每...
在网上学习jsp自定义标签的时候, 出现了异常, 在网上寻找了好久, 都没有找到合适的答案, 自己通过摸索最后成功, 分享给大家, 希望能够帮助到你, 自定义标签不能放在java Project中, 只能在java web Project中才可以.
java jsp自定义标签非常好用大家下载学习java jsp自定义标签非常好用大家下载学习java jsp自定义标签非常好用大家下载学习java jsp自定义标签非常好用大家下载学习java jsp自定义标签非常好用大家下载学习java jsp...
创建JSP自定义标签.doc 创建JSP自定义标签.doc 创建JSP自定义标签.doc
JSP自定义标签。在自定义标签的起始和结束标签之间的部分为标签体(Body)。 标签处理程序类:定义标签的行为,并在JSP引擎遇到自定义标签时调用执行。 标签库描述符(TLD)文件:描述标签库的XML文档,向JSP引擎...
JSP自定义Table标签demo JSP自定义Table标签demo JSP自定义Table标签demo
jsp、jstl自定义标签实现的分页,实现的还是比较好的,没有在request、session等范围保存过数据,在pageContext范围内保存过集合的数据, 实现的方法还是比较简单的,适用性还是比较广的,我是实在是没分了,平时也...
jsp自定义迭代标签 jsp自定义迭代标签
jsp自定义标签库实现数据列表显示,包括代码,文档,希望对大家有帮助.
jsp自定义嵌套标签 自定义嵌套标签的定义和使用
是用jsp自定义标签编写的一个非常不错的分页,扩展性非常不错,不依赖于数据库。