我们都知道,通过使用JSP中的标记库可以减少展现层中的Java代码,使得修改、维护和阅读起来都比较方便。
<%
String format ="yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(format);
String date = sdf.format(new Date());
out.println(date);
%>
在未使用JSP标记库时,要书写大量的Java代码,使得页面凌乱难以维护、修改和阅读。如果使用JSP标记库,则可以简化为如下:
<util:date/>
显而易见,JSP标记库使Java代码书写量大大减少,功能也强大。
现在简单的介绍一下这个标记,“util”是标记的前缀,因为在一个JSP页面中可能会使用多个不同的标记,不同的标记库又可能
有同名的标记,为了解决标记重名的问题,所以在这里使用了“前缀标识法”,每个定制标记库都是用不同的前缀。“date”是这个标记的名称,当执行到JSP中的这行定制标记的时候,会调用对应的标记处理类中所对应的方法,输出日期信息。所以使用了定制标记库的JSP页面再转换成对应的servlet文件后,在生成的Servlet文件中会包括调用标记处理类对应的方法的Java代码。
下面编写一个自己定义的标记库:
学习目标:编写一个自己的标记库,了解编写定制标记库的基本步骤和方法。
1.编写标记处理类
/**
*计算代码段运行时间的Tag Handler类,会输出标记包含的代码段运行的时间
*/
public class TimerTag extends TagSupport {
private static final long serialVersionUID = 1L;
private long start;
private long end;
/**
*执行到开始标记调用的方法,设定计时的起点
*/
public int doStartTag(){
start = System.currentTimeMillis();
return EVAL_BODY_INCLUDE;
}
/**
*执行到开始标记调用的方法,设定计时的起点
*/
public int doEndTag()throws JspTagException{
end = System.currentTimeMillis();
long elapsed = end - start;
try{
JspWriter out = pageContext.getOut();
out.println("running time : " + elapsed + "ms");
}catch(IOException e){
throw new JspTagException(e);
}
return EVAL_PAGE;
}
}
TimerTag类继承了javax.servlet.jsp.tagext.TagSupport类,重写了doStartTag()和doEndTag()方法。
当JSP页面执行到timer标记的开始标记的时候,就会调用doStartTag()方法,给start变量赋给当前时间的数值。
EVAL_BODY_INCLUDE,这个常量表示会运行定制标记所包含的JSP页面的内容。
当JSP页面执行到timer标记的结束标记时,就会调用doEndTag()方法,给end变量赋表示当前时间的数值。在标记的处理类中不能像JSP页面一样直接使用JSP的out内置对象进行内容输出,而必须先通过pageContext对象的getOut()方法获得out内置对象,然后再调用out对象进行输出。同理,在标记处理类的内部,使用任何JSP内置对象,都要先通过调用pageContext()对象的对应的get方法。例如:如果要获得session对象,则可以通过getSession()方法获得。EVAL_PAGE表示这个标记之后的JSP页面内容可以继续运行。
2.编写util.tld文件
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeeweb-jsptablibrary_2_1.xsd"
version ="2.1" >
<tlib-version>1.0</tlib-version>
<short-name>util</short-name>
<uri>http://crazy.com/taglib/util</uri>
<display-name>utilitytags</display-name>
<description>custom web utility tags</description>
<tag>
<name>Timer</name>
<tag-class>practice.TimerTag</tag-class>
<body-content>JSP</body-content>
</tag>
</taglib>
在web项目中使用定制标记库,还需要编写定制标记的配置描述文件,该文件是一个XML文件,所以要遵守xml文件的规则。编写好了,保存到WebRoot/WEB_INF目录下。
util.tld文件时当前定制标记库的配置文件,标记库中所有的标记都要在这个文件中进行配置后才能被JSP页面中使用。
<short-name>util</short-name>
是设定这个标记库推荐使用的前缀名称。
<body-content>JSP</body-content>
设定对标记所包含的内容如何处理,可以使用JSP,empty,tagdependent和scriptlesss。设定为JSP表示所包含的内容如果是JSP内容,将会先执行JSP代码,再把执行后的结构传给标记处理类。而Scriptless表示标记所包含的内容部能是Scriptlet内容,但是可以是EL或 JSP动作等其他JSP元素;tagdependent表示对所包含的内容部做任何处理,直接将内容传给标记处理类,由标记处理类自行处理。empty表示标记不能包含内容。
3.编写一个JSP文件测试一下自己编写好的标记库。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib prefix="util" uri="http://crazy.com/taglib/util"%>
<html>
<head></head>
<body>
<util:Timer>
<%
for(int i =0;i<1000000;i++);
%>
</util:Timer>
</body>
</html>
将其部署一下,然后运行一下看看结果。