完全引用~
来源:http://blog.csdn.net/miocn/article/details/491847
在J2EE项目中,JSP页面常常通过在静态页面模板中嵌入scriptlets来插入动态的内容。然而,随着复杂程序的增加,JSP页面也变得难于管理。 虽然用这种方法开发小形项目唾手可得,但是scriptlets仍然要面对下面的不利情况:
- Scriptlet难于阅读和修改。带有Scriptlets的JSP页面混合了两种语言,这使得阅读和维护变得很困难。
- Scriptlets鼓励了将数据表现和逻辑处理的混合 。JSP页面主要功能是数据表现而不是逻辑处理。逻辑处理属于Java类的工作,他们应该由程序员维护并能够重用。
- Scriptlets不能够被重用。当scriptlets被重用时,常常是鼓励拷贝-粘贴来达到重用的效果,这是一种危险的维护方法。每一次你拷贝-粘贴scriptlets时,将有更多行多余的代码需要维护。
- Scriptlets的参数很难进行确定传递. 无论如何,绝大数人简单的拷贝,粘贴、编辑或者类似的增加,使得大部份的多余的代码需要更多的维护。
与其创建充满了scriptlets的巨大的JSP页面,不如考虑使用用户自定义标签。用户自定义标签允许你创建、在JSP中使用你自己定义的类HTML标签。每当JSP引擎遇到用户自定义标签时,就会自动查找标签处理类,并自动调用他。页面中的自定义标签将会被票签处理类的输出所代替。这就使得JSP页面不用直接在页面写Java代码,就可以指定生成动态的内容的。
用户自定义标签为你的网页设计提供了N种好处:他提高了页面代码的可读性。页面设计人员而不是程序员,能够使用很比使用Scriptlets更容易的使用标签。维护代码的程序员也只需个性标签库面不是JSP页面,这样他就不要再冒着破坏页面美观的风险。 在使用标签的每一处,增强或者固定的标签改变了标签了的表现。标签比Scriptlets更容易确定参数,因为他会被 作为一种属性或者在标签体内被传达。最后,标签比Scriptlets高度的可重用性,因为你可以创建共享的、可重用的自定义标签库。 JSTL提供的就是这种标准的自定义标签集。
让我们通过看一个简单的JSP页面例子,来看看如何使用自定义标签。 下面这个页面使用scriptlet来得到数据:
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<HTML>
<HEAD><TITLE>Sample JSP</TITLE></HEAD>
<BODY>
<H3>
The date and time at the server are:
<%
String sformat = "EEEE, d MMMM yyyy 'at' kk:mm:ss z";
SimpleDateFormat format = new SimpleDateFormat(sformat);
Date date = new Date();
String sdate = format.format(date);
out.print(sdate);
%>
</H3>
</BODY>
</HTML>
这个页面非常的简单直接,尽管这个简单的函数看上去好像有许多东东。如果你想要在每一个页面上显示日期,那么你只能拷贝粘贴这段代码到项目中的每一个页面。如果你这么做,那么你要维护的不仅仅是这段代码的原始拷贝,而是你粘贴的每一个拷贝。 如果这段代码出现在多个页面,那么改变一下时间格式将会占用你的很多时间。
下面这段是一个非常清洁的JSP页面。在这里,Java代码被从scriptlet中移出放到了自定义标签中:
<%@ taglib uri="/WEB-INF/taglib.tld" prefix="mytags" %>
<HTML>
<HEAD><TITLE>Sample JSP using a custom tag</TITLE></HEAD>
<BODY>
<H3>
The date and time at the server are: <mytags:date/>
</H3>
</BODY>
</HTML>
在这个例子中,<@% taglib %>用来指出自定义标签描述符文件路径(标签库中的描述符或者TLD文件),并且为这个标签名定义一个名字空间(“mytags”,可是你喜欢的任何字符)。JSP引擎认可<mytags:date/>作为一个用户定义标签的符号,他会调用这个标签的标签处理器,并用处理结果替换标签和内容。
创建一个用户定义标签处理器
创建一个用户定义标签处理器需要比定scriptlet多一定量的工作,因为这一个Java类,并且你不得不为他写一个TLD格式(在下一节介绍)的描述符文件。下面这个类DataTag实现了一个标签处理器:
public class DateTag extends TagSupport {
protected PageContext _pageContext;
protected String _sFormat;
static final String _sFormatDefault =
"EEEE, d MMMM yyyy 'at' kk:mm:ss z";
public void setPageContext(PageContext pageContext) {
_pageContext = pageContext;
_sFormat = _sFormatDefault;
}
// Handle the tag
public int doStartTag() throws JspException {
SimpleDateFormat format =
new SimpleDateFormat(getFormat());
JspWriter out = _pageContext.getOut();
Date date = new Date();
String sdate = format.format(date);
try {
out.print(sdate);
} catch (IOException ex) {
throw new JspException("DateTag: can't write: " +
ex.getMessage());
}
return SKIP_BODY;
}
// Handlers for "format" attribute
public void setFormat(String sFormat) {
_sFormat = sFormat;
}
public String getFormat() {
return _sFormat;
}
}
TagSupport实现了标签处理器要求的所有接口。这些方法本来没有做什么任何事,标签处理器开发人员重构了需要方法,允许基类处理调用所有的其他的方法。标签处理器每一次被调用都会调setPageContext方法。 这个类为稍后便用简单的保存了PageContext参照。
当JSP引擎遇到这个标签时会调用doStartTag方法。这个方法和第1个版本JSP页面的scriptlet处理了相同的事。他将结果写回给JspWriter,结果包括了先存储的PageContext.所有写给JspWriter的内容,会被直接嵌入到响应页面。 注意doStartTag只能抛出JspException异常。如果发生写失败,那么原始IOException会被转化成一个JspException重新抛出。这个方法会返回SKIP_BODY,他告诉JSP容器抛弃标签内容。
标签处理器最后的两个方法是setFormat和getFormat。机敏的读者应该已经知道了他作用。 他被网页容器用来设置标签属性值(后面进行更详细的讨论)。在这儿他们被用来设定日期格式属性和输出日期格式属性。
标签定义:TLD文件
一个标签库描述符文件, 或者TLD文件, 是一个XML文件。他用来描述标签库中的标签。以下是DateTag标签的描述文件。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>first</short-name>
<uri>http://www.elucify.com/j2eetips/sept2002/taglib</uri>
<description>Sample tag library</description>
<tag>
<name>date</name>
<tag-class>com.elucify.tips.sep2002.DateTag</tag-class>
<body-content>empty</body-content>
<description>Print the date with a compiled-in format</description>
<attribute>
<name>format</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
这些描述符提供了这个标签库的信息。他还提供了每一个标签的如标签名、处理器的类和标签描述的信息。这个文件被用来替换WEB-INF目录下的WAR文件,为JSP页面使用这些标签提供参照。
增加属性
Notice that the TLD file shown above defines an attribute called format. This is the string passed to SimpleDateFormat to control how the date is printed. If a format attribute is present on a date tag, the JSP engine calls setFormat on the handler class. Otherwise, the handler class uses a default format. Attributes provide a great deal of customizability to custom tags. For example, the following JSP page uses the format attribute to format the date in several different ways on the same page:
注意上面这个TLD文件显示的属性调用格式 。这是一个字符串被传递给SimpleDateFormat,来控制如何显示日期。如果一个日期格式被提供给日期标签,那么JSP引擎将调用控制器类中的setFormat方法 ,否则,标签处理器将使用默认格式。属性为用户定义标签提供了大量可定制属性。例如以下这个例子,在同一个页面的, 用几种不同的格式属性来格式化时间。
<%@ taglib uri="/WEB-INF/taglib.tld" prefix="mytags" %>
<HTML%>
<HEAD><TITLE%>Sample JSP using a custom tag and format</TITLE%></HEAD%>
<BODY%>
<H3%>
The time zone at the server is <mytags:date format="zzzz"/%>.<br%>
The server date is <mytags:date format="M/d/yyyy"/%>.<br%>
The server time is <mytags:date format="hh:mm:ss a"/%>.<br%>
</H3%>
</BODY%>
</HTML%>
想像一下,如果使用scriptlets,做同样的事情,将会要多少行多余的代码。
布署使用自定义标签的JSP页面
标签处理器可以放在WEB-INF/classes目录下,和TLD分离。 或者也可以将一组想关的标签和TLD文件绑定成JAR文件,提供一个单一的布署。这个例子使用的是第一个方法。这不需要在web.xml中增加任何布署描述。
用户自定义标签大大提高了JSP页面动态内容代码的可读性、可伸缩性、可重用性和可维护性。
自定义标签资源
You can learn how to implement several kinds of custom tags in the J2EE Tutorial section Custom Tags in JSP Pages. Also see the JavaServer Pages Standard Tag Library page. The Enterprise Java BluePrints has several best practices for Web components, including JSP pages and custom tags. Among other features, JavaServerTM Faces technology provides a large library of general-purpose custom tags.文章来源: http://blog.csdn.net/miocn/article/details/491847