JSP 自定义标记是 JSP/JavaBean 体系结构的产物。像 JavaBean 技术一样,自定义标记有助于将表示逻辑与业务逻辑分离。并且自定义标记成了 Web 设计者的 HTML、XML 和 Javascript 世界与软件工程师的 Java 代码、SQL 调用和算法世界之间的桥梁。
JSP 自定义标记
JSP 自定义标记是用户定义的标记,它遵循 JSP JavaBean 标记(即 useBean 、 getProperty 和 setProperty )所使用的一种特殊的 XML 语法。当 servlet 容器处理自定义标记时,会调用一个或者多个 Java 类文件处理它,与用 Java 类文件处理 JSP 页面的 JavaBean 调用的方式基本一样。处理标记以后,容器将取其名字和属性、以及标记正文中可能有的任何内容,并将它传递给一个或者多个类文件进行处理。
Java 开发人员编写标记处理程序类以处理标记并处理所有需要的 Java 代码和数据操作。对于 Web 设计者来说,自定义标记与标准 HTML 标记除了都可以利用后端动态数据外,它们看上去与使用起来没什么区别。正确编写自定义标记可以让 Web 设计者创建、查询和操作数据而无需编写一行 Java 代码。正确使用自定义标记使 Java 开发人员不必再在编码过程中考虑表示层。这样应用程序开发小组的每一位成员都可以关注于他或者她最擅长的事物。
实现 JSP 自定义标记
JSP 体系结构需要以下组件以实现自定义标记:
在每一页中有一个 JSP 声明
Web 应用程序描述符(web.xml)中的一个项
一个包含特殊 XML 文件和为处理自定义标记而调用的 Java 类的 JAR 文件
在下面几节,您将一步一步地学习如何满足这些要求并将自定义标记加入到 JSP 页面中。要想成功实现 JSP 自定义标记,您需要采取下面五个步骤:
- 编写标记处理程序类。
- 创建标记库描述符(TLD)。
- 使 TLD 文件和处理程序类可访问。
- 引用标记库。
- 在 JSP 页面中使用标记。
这些内容是相当基本的,也不用花很长时间。就让我们开始吧。
第1步. 编写标记处理程序类
在下面的例子中,我们将使用一个非常简单的显示当前时间和日期的自定义标记例子。下面就是 DateTag :
<abc:displayDate />
我们要做的第一件事是编写标记处理程序类。在执行引用自定义标记的 JSP 页面时,JSP 容器判断每一个自定义标记。当容器遇到一个标记时,它调用与这个自定义标记相关联的标记处理程序,我们将在后面更多地讨论这个过程。然后,每一个标记处理程序实现 JSP API 中的一个特殊接口。标记有两种类型:可以处理标记内容(或者正文)的标记和不能处理标记内容的标记:
1 <abc:tagWithNoBody attribute="value"/> 2 <abc:tagWithBody attribute="value"> 3 This is some body content that the tag handler can operate upon. 4 </abc:tagWithBody> |
在 DateTag 例子中不需要加入正文内容,因为它只显示当前日期。因此,我们的处理程序类将实现 Tag 接口(一般是通过扩展 TagSupport 类)。如果我们要创建一个可以处理正文的标记,那么我们就需要实现 BodyTag 接口(一般是通过扩展 BodyTagSupport 类)。清单 1 显示了 DateTag 的处理程序类:
清单 1. 标记处理程序类
1 package myTags; 2 import javax.servlet.jsp.tagext.*; 3 import javax.servlet.jsp.*; 4 import javax.servlet.http.*; 5 import java.text.*; 6 import java.util.*; 7 public DateTag extends TagSupport { 8 9 public int doStartTag() throws javax.servlet.jsp.JspException { 10 HttpServletRequest req; 11 Locale locale; 12 HttpJspPage g; 13 DateFormat df; 14 String date; 15 JSPWriter out; 16 17 req = ( HttpServletRequest )pageContext.getRequest(); 18 locale = req.getLocale(); 19 df = SimpleDateFormat.getDateInstance( 20 SimpleDateFormat.FULL,locale ); 21 date = df.format( new java.util.Date() ); 22 23 try { 24 out = pageContext.getOut(); 25 out.print( date ); 26 } catch( IOException ioe ) { 27 throw new JspException( "I/O Error : " + ioe.getMessage() ); 28 }//end try/catch 29 return Tag.SKIP_BODY; 30 }//end doStartTag() 31 }//end DateTag |