Servlet&JSP的那些事儿(二十四)

本篇我们讨论标签文件(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。运行结果如下:

Servlet&JSP的那些事儿(二十四)_第1张图片

我们在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

你可能感兴趣的:(jsp,jsp,jsp,tag,Files)