本篇我们讨论标签文件(Tag Files)。之前我们在Servlet&JSP的那些事儿(十六)、Servlet&JSP的那些事儿(十六)两篇中讨论过了传统标签和简单标签的开发,需要使用java语言编写标签处理器类,标签文件允许jsp页面编写人员使用jsp语法来定制标签,不需要了解java语言。本篇我们主要介绍如何标签文件来定制标签。如果能和之前的两篇结合起来,会更好的理解标签文件。
标签文件的语法
它的语法和jsp语法有点类似,在jsp页面中可以使用的语法在标签文件中可以使用,不过有不同之处。
1)jsp页面中的page指令在标签文件中不能使用,标签文件增加了tag指令、attribute指令和variable指令。
2)<jsp:invoke>和<jsp:doBody>两个标准动作元素只能在标签文件中使用。
我们先看一个简单的标签文件hello.tag。如下
<%@ tag pageEncoding="gb2312" %> 这是一个标签文件
tag指令只能在标签文件中使用,用于取代jsp页面中的page指令。
编写的标签文件要在jsp页面中使用,需要存放在指定位置。包括两个地方:一是放在/WEB-INF/tags目录或其子目录下,容器会自动搜索其中的.tag和.tagx文件。二是放在JAR文件的/META-INF/tags目录或其子目录下。
现在编写一个jsp页面测试一下。如下所示:
<%@ page contentType="text/html;charset=gb2312" %> <%@taglib tagdir="/WEB-INF/tags" prefix="mytag"%> <html> <head><title></title></head> <body><mytag:hello/></body> </html>
注:在taglib指令中,属性tagdir指定标签文件所在的路径。
可以启动tomcat,访问该页面。在浏览器网址栏输入http://localhost:8080/TestTag/hello.jsp。运行结果如下:
我们在D:\apache-tomcat-7.0.33\work\Catalina\localhost\TestTag\org\apache\jsp\tag文件夹下,可以找到一个webhello_tag.java文件。内容如下:
/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/7.0.33 * Generated at: 2012-12-14 08:32:17 UTC * Note: The last modified time of this file was set to * the last modified time of the source file after * generation to assist with modification tracking. */ package org.apache.jsp.tag; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class webhello_tag extends javax.servlet.jsp.tagext.SimpleTagSupport implements org.apache.jasper.runtime.JspSourceDependent { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private javax.servlet.jsp.JspContext jspContext; private java.io.Writer _jspx_sout; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public void setJspContext(javax.servlet.jsp.JspContext ctx) { super.setJspContext(ctx); java.util.ArrayList _jspx_nested = null; java.util.ArrayList _jspx_at_begin = null; java.util.ArrayList _jspx_at_end = null; this.jspContext = new org.apache.jasper.runtime.JspContextWrapper(ctx, _jspx_nested, _jspx_at_begin, _jspx_at_end, null); } public javax.servlet.jsp.JspContext getJspContext() { return this.jspContext; } public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } private void _jspInit(javax.servlet.ServletConfig config) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(config.getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(config); } public void _jspDestroy() { } public void doTag() throws javax.servlet.jsp.JspException, java.io.IOException { javax.servlet.jsp.PageContext _jspx_page_context = (javax.servlet.jsp.PageContext)jspContext; javax.servlet.http.HttpServletRequest request = (javax.servlet.http.HttpServletRequest) _jspx_page_context.getRequest(); javax.servlet.http.HttpServletResponse response = (javax.servlet.http.HttpServletResponse) _jspx_page_context.getResponse(); javax.servlet.http.HttpSession session = _jspx_page_context.getSession(); javax.servlet.ServletContext application = _jspx_page_context.getServletContext(); javax.servlet.ServletConfig config = _jspx_page_context.getServletConfig(); javax.servlet.jsp.JspWriter out = jspContext.getOut(); _jspInit(config); jspContext.getELContext().putContext(javax.servlet.jsp.JspContext.class,jspContext); try { out.write("\r\n"); out.write("这是一个标签文件"); } catch( java.lang.Throwable t ) { if( t instanceof javax.servlet.jsp.SkipPageException ) throw (javax.servlet.jsp.SkipPageException) t; if( t instanceof java.io.IOException ) throw (java.io.IOException) t; if( t instanceof java.lang.IllegalStateException ) throw (java.lang.IllegalStateException) t; if( t instanceof javax.servlet.jsp.JspException ) throw (javax.servlet.jsp.JspException) t; throw new javax.servlet.jsp.JspException(t); } finally { jspContext.getELContext().putContext(javax.servlet.jsp.JspContext.class,super.getJspContext()); ((org.apache.jasper.runtime.JspContextWrapper) jspContext).syncEndTagFile(); } } }从代码中可以看出,这个类继承自javax.servlet.jsp.tagext.SimpleTagSupport类,也就是说,标签文件本质上就是简单标签。所以标签文件和简单标签本质上并没有什么不同。
标签文件的隐藏属性
标 签文件可以使用隐藏属性:request、response、jsContext、session、application、out、config,其中 jspContext隐含对象的类型为javax.servlet.jsp.JspContext,它用来管理所有范围的变量,就相当于JSP页面的 pageContext隐藏对象一样
标签文件的指令
标签文件中可以使用的主要指令:taglib、include、attribute、variable。
<%@ tag display-name="" body-content="" dynamic-attributes="" small-icon="" large-icon="" description="" example=""language="" import="" pageEncoding="" isELIgnored="">
tag 指令如同JSP网页的page指令,用来设定标签文件。display-name表示图形化开发工具显示<display-name>所指定 的名称;body-content表示可能的值有三种,分别是empty、scriptless、tagdependent、empty。empty为标 签中没有主体内容,scriptlet为标签中的主体内容EL、JSP动作元素,但不可以为JSP脚本元素,tagdependent表示标签中的主体内 容交由tag自己去处理,默认值为scriptless;dynamic-attributes表示设定标签文件动态属性的名称,当dynamic- attributes设定时,将会产生一个Map类型的集合对象,用来存放属性的名称和值;small_icon表示在图形化开发工具显 示<small-icon>所指定的TLD相对路径的小图标,大小为16X16;large-icon表示在图形化开发工具显 示<large-icon>所指定的TLD相对路径的大图标,大小为32X32;description表示用来说明此标签文件的相关信 息;example表示用来增加更多的标签使用说明,包括标签应用时的范例;language、import、pageEncoding、 isELIgnored这些属性与page指令相对应的属性相同。
<%@ attribute name="" required="" fragment="" rtexprvalue="" type="" description=""%>
这 个指令用来设定自定义标签的属性。其中name表示属性的名字;required表示是否为必要,默认为false;rtexprvalue表示属性值是 否可以为run-time表达式。如为true,表示属性可用动态的方式来指定,如:<mytag:read num="${param.num}"/>,如为false,则一定要用静态的方式来指定属性值;type表示这个属性的类型,默认值为 java.lang.String;description用来说明此属性的相关信息。
<%@ variable name-given="" name-from-attribute="" alias="" variable-class="" declare="" scope="" desription="">
这 个指令用来设定标签文件的变量。其中name-given表示直接指定变量的名称;name-from-attribute表示以自定义标签的某个属性值 为变量名称;alias表示声明一个局部范围属性,用来接收变量的值;variable-class表示变量的类名称,默认值为 java.lang.String;declare表示此变量是否声明默认值为true;scope表示此变量的范围,范围是:AT_BEGIN、 AT_END和NESTED,默认值为NESTED;description用来说明此变量的相关信息。
<jsp:invoke>动作元素
该元素将JspFragment类型的属性的执行结果输出到JspWriter对象,或者保存到指定的范围变量中。
<jsp:invoke fragment="frag" var="resultString" varReader="resultReader" scope="scope" />
frament为必须的属性,用于指定类型为JspFragment的属性的名称。var是可选属性,指定一个范围变量的名字,类型是string。该变量保存了JspFragment对象执行的结果。属性var和属性varReader只能指定其一,如果两者都没指定,则JspFragment对象的执行结果输出到当前的JspWriter对象中。varReader将JspFragment对象执行的结果保存到Reader类型的变量中。scope用来指定变量的jsp范围内。默认为page。
<jsp:doBody>动作元素
该标签用于执行标签体(JspFragment对象),将结果输出到JspWriter对象,或者保存到指定的范围变量中。
转载请注明出处:http://blog.csdn.net/iAm333