(转)掌握jsp自定义标签:(六)

原创 2004年07月30日 23:33:00
概述 第 1 页(共4 页)


有时,可能希望根据一些特定于应用程序的显示逻辑有条件地调用方法的正文。可以通过从 doStartTag() 返回一个值做到这一点:SKIP_BODY 跳过标签的正文,而 EVAL_BODY 对它进行判断。

迭代标签需要实现 IterationTag 接口。容器调用 doAfterBody() 方法以确定是否要重新判断正文。这个方法返回 EVAL_BODY_AGAIN 时表明容器应当继续对正文进行判断。doAfterBody() 方法返回 SKIP_BODY 时表明迭代操作已经结束。TagSupport 类和 BodyTagSupport 类都实现了 IterationTag 接口。

回到 map 主题,在下面几小节我们将创建一个自定义标签处理程序,它迭代一组 map 并打印出它们的值。

控制流程序示例 第 2 页(共4 页)


在开始实现自定义标签处理程序之前,让我们看看示例标签是如何使用的。首先,用上面的例子中的 map 标签定义两个 map:

 <%@taglib uri="map" prefix="map"%>   <?xml:namespace prefix = map /> { firstName=Jennifer, lastName=Wirth, age=33 }  { firstName=Kiley, lastName=McKeon, age=27 }  

然后,创建一个名为 list 的集合,加入上面定义的两个 map (employee1employee2)。

 <?xml:namespace prefix = jsp /> <% list.add(employee1); list.add(employee2); %>  

下面展示了如何用自定义标签迭代这个集合:

 
First Name${firstName} Last Name ${lastName} Age${age}

map:printMaps 标签迭代 list 集合。 在每一次迭代时,它使用其正文,通过搜索以 ${key} 开始的子字符,在 map 中搜索当前迭代的键。它从字符串 ${} 中解析出键,并用从 map 得到的这个键的值(即 map.get(key))替换它。

实现 doStartTag() 方法 第 3 页(共4 页)


doStartTag() 方法从范围中抓取集合,然后从集合中抓取迭代器。 如果迭代器中没有任何项(iter.hasNext()),那么 doStartTag() 方法就返回 SKIP_BODY,从而实现了逻辑 if。在这种情况下,这个 if 等同于“如果集合为空,则跳过正文判断”。 然后迭代器从集合中抓取第一个 map。

 public class MapPrintMapsTag extends BodyTagSupport { private String name; private Iterator iter; private Map map; private String scope; public int doStartTag() throws JspException { Collection collection = null; /* Grab the collection out of scope using the scope attribute. */ if (scope == null){ collection = (Collection) pageContext.findAttribute(name); }else if("page".equalsIgnoreCase(scope)){ collection = (Collection) pageContext.getAttribute(name); }else if("request".equalsIgnoreCase(scope)){ collection = (Collection) pageContext.getRequest().getAttribute(name); }else if("session".equalsIgnoreCase(scope)){ collection = (Collection) pageContext.getSession().getAttribute(name); }else if("application".equalsIgnoreCase(scope)){ collection = (Collection) pageContext.getServletContext().getAttribute(name); } /* Get the iterator from the collection. */ iter = collection.iterator(); /* If the collection is empty skip the body evaluation. */ if (iter.hasNext()==false) return SKIP_BODY; /* Grab the first map out of the collection. */ map = (Map)iter.next(); return EVAL_BODY_BUFFERED; } 
实现 doAfterBody() 方法第 4 页(共4 页)

doAfterBody() 通过在没有可迭代的项时返回 SKIP_BODY 实现了迭代。如果还有项,那么它就返回 EVAL_BODY_AGAIN。只要 doAfterBody() 返回 EVAL_BODY_AGAIN,容器就会继续对正文进行判断,如下所示:

 public int doAfterBody() throws JspException { /** Process body */ ... /** Write the processed buffer to the previous out */ ... if (iter.hasNext() == false) { return SKIP_BODY; } else { map = (Map) iter.next(); return EVAL_BODY_AGAIN; } }  

doAfterBody() 方法用 getBodyContent() 抓取正文,然后用正文内容的 getString() 方法得到字符串形式的内容。 下一步它清除正文内容缓冲区,用 StringTokenizer 查找以 ${ 开始的字符串。 它还创建一个名为 bufferStringBuffer。 当它迭代 tokenizer 中的字符串时,将它们附加到缓冲区中。

如果 tokenizer 中的字符串以 ${, doAfterBody() 开始,那么它就从字符串中提取键,并用这个键在 map 中查找值。它调用值对象的 toString() 方法将 map 中的值转换为字符串,并将结果附加到缓冲区中。下面的清单展示了这个过程是如何进行的。

 /** Process body */ /* Get and clear the body */ BodyContent body = this.getBodyContent(); String content = body.getString(); body.clearBody(); /* Process the body with a String tokenizer */ StringTokenizer token = new StringTokenizer(content); /* Create an output buffer of the processed body */ StringBuffer buffer = new StringBuffer(content.length() * 2); /* Iterate over the strings from the tokenizer and put them into the output buffer. */ while (token.hasMoreTokens()) { String tok = token.nextToken(); /* See if the String contains the special substring "${" */ if (tok.startsWith("${")) { /* Parse the key out of the string */ String key = tok.substring(2, tok.length() - 1); /* Use the key to look up the object in the map */ Object value = (String) map.get(key); String svalue = tok; /* If the value is not null, get the value's string representation */ if (value != null) { svalue = value.toString(); } /* Add the string representation of the value to the output buffer */ buffer.append(svalue + " "); } else { buffer.append(tok + " "); } }  

doAfterBody() 方法在构建了输出缓冲区后,就将它输出到前面的 out 中,如下所示:

 try { this.getPreviousOut().print(buffer.toString()); } catch (IOException e) { throw new JspException(e); }  

这样,每一次迭代都处理正文并将它输出到前面的 out 中。如果前面的 out 是根 JspWriter,那么它就会写到浏览器中。

(转)掌握jsp自定义标签:(六)

概述 第 1 页(共4 页) 有时,可能希望根据一些特定于应用程序的显示逻辑有条件地调用方法的正文。可以通过...
  • hb_cattle
  • hb_cattle
  • 2007-03-29 20:49:00
  • 490

掌握jsp自定义标签chm版

  • 2008年03月25日 12:22
  • 166KB
  • 下载

JSP:自定义标签之开发html转义标签

超链接的写法 package cn.itcast.web.tag.example;   import java.io.IOException; import java.io...
  • xxssyyyyssxx
  • xxssyyyyssxx
  • 2015-11-25 09:20:10
  • 830

JSP自定义标签总结

在JAVA项目开发中,JSP自定义标签,可以使前端的展现简洁与方便。JSP的自定义标签从广义上来说,有2种形式,一种是需要进行DOM内容展示的,需要进行继承SimpleTagSupport类并重写的d...
  • simon_xu_sh
  • simon_xu_sh
  • 2016-11-21 16:12:06
  • 2587

(转)掌握jsp自定义标签:(二)

简单标签的例子 第 1 页(共9 页) Struts 框架带有几个自定义标签库(有关 Struts 的更多信息的链接请参阅 参考资料 )。这些库中的一个标签可以创建一个支持改写 URL 的链接并...
  • nighthawk
  • nighthawk
  • 2004-07-30 23:26:00
  • 1924

(转)掌握jsp自定义标签:(一)

本教程目的 第 1 页(共3 页) 想要在 JavaServer Pages (JSP) 应用程序中添加自定...
  • hb_cattle
  • hb_cattle
  • 2007-03-29 20:44:00
  • 619

(转)掌握jsp自定义标签:(七)

结束语 第 1 页(共3 页) 学完本教程,您对自定义标签有了更深入的理解。如果您学完了本教程,即便是刚接触...
  • hb_cattle
  • hb_cattle
  • 2007-03-29 20:50:00
  • 482

(转)掌握jsp自定义标签:(三)

第 3 步:在标签处理程序 Java 类中创建属性 第 5 页(共9 页) 我们希望为 mapDefine 标签指定三个属性,如下所示: 属性说明 id 新 scriptlet 变量...
  • nighthawk
  • nighthawk
  • 2004-07-30 23:27:00
  • 1522

(转)掌握jsp自定义标签:(五)

用 Reflection 将 beann 属性提取为值 第 2 页(共3 页) 开发人员通常使用 Java ...
  • hb_cattle
  • hb_cattle
  • 2007-03-29 20:49:00
  • 593
收藏助手
不良信息举报
您举报文章:(转)掌握jsp自定义标签:(六)
举报原因:
原因补充:

(最多只允许输入30个字)