`
xiaoyezi1128
  • 浏览: 131543 次
  • 性别: Icon_minigender_2
  • 来自: 天津
社区版块
存档分类
最新评论

jsp tag

阅读更多


本文基于Apache Tomcat v5.0。

1 Tag handler
1.1 重用

   Tag handler被保存在org.apache.jasper.runtime.TagHandlerPool对象池中,以下是TagHandlerPool的几个方法: 

    * public TagHandlerPool() 用缺省容量构造TagHandlerPool
    * public Tag get(Class handlerClass) throws JspException 从对象池中取出下个可用的tag handler。如果对象池为空,则实例化一个tag handler(需要注意的是,这个新实例化的tag handler并不被对象池管理)。如果tag handler无法被实例化,那么抛出JspException异常。
    * public void reuse(Tag handler) 把tag handler放回到对象池中等待重用。如果对象池已经达到了容量上限,那么调用tag handler上的release方法。
    * public void release() 在对象池中所有可用的tag handler上调用release方法。

   除了TagHandlerPool之外,还有一个org.apache.jasper.runtime.PerThreadTagHandlerPool对象池。它继承自TagHandlerPool。顾名思义,它是一个基于Thread local的对象池。

   需要注意的是,与继承自TagSupport 和BodyTagSupport 的tag handler不同,实现SimpleTag接口 的tag handler不再被JSP容器缓存。



1.2 TagSupport
    在取得了tag handler之后,JSP容器首先会调用tag hander上的setPageContext(PageContext pc)方法,因此在tag handler的构造函数中不能访问pageContext。之后调用setParent(Tag t)方法和其它属性的注入。
    当遇到标签的起始标记,就会调用public int doStartTag() throws JspException方法。这个方法有Tag.SKIP_BODY和Tag.EVAL_BODY_INCLUDE两个可选的返回值。缺省返回Tag.SKIP_BODY。返回Tag.SKIP_BODY意味着标签之间的内容被忽略;返回Tag.EVAL_BODY_INCLUDE意味着标签之间的内容将被执行。
    如果doStartTag()方法返回值不是Tag.SKIP_BODY,而且在Tag Library Descriptor(tld)文件中该tag的bodycontent属性不是empty,那么在标签之间的内容执行完毕后,就会调用public int doAfterBody() throws JspException方法,这个方法有Tag.SKIP_BODY和IterationTag.EVAL_BODY_AGAIN两个可选的返回值。缺省返回Tag.SKIP_BODY。返回IterationTag.EVAL_BODY_AGAIN意味着标签之间的内容将被执行,然后会再次调用doAfterBody()方法;返回Tag.SKIP_BODY意味着标签之间的内容不再被执行。
    当遇到标签的结束标志,就会调用public int doEndTag() throws JspException方法。这个方法有Tag.EVAL_PAGE和Tag.SKIP_PAGE两个可选的返回值。缺省返回Tag.EVAL_PAGE。返回Tag.EVAL_PAGE意味着按照正常的流程继续执行JSP网页;返回Tag.SKIP_PAGE意味着JSP网页上未处理的部分均被忽略。


1.3 BodyTagSupport
    BodyTagSupport继承了TagSupport,并且实现了BodyTag接口。以下是在BodyTag中声明的两个方法:
Java代码

   1. void setBodyContent(BodyContent b); 
   2. void doInitBody() throws JspException; 

void setBodyContent(BodyContent b);
void doInitBody() throws JspException;

   BodyTagSupport可以用于访问标签体。与TagSupport的doStartTag()方法不同的是,BodyTagSupport的 doStartTag()方法多了一个可选的返回值BodyTag.EVAL_BODY_BUFFERED。如果doStartTag()方法返回值是 BodyTag.EVAL_BODY_BUFFERED,而且在Tag Library Descriptor(tld)文件中该tag的 bodycontent属性不是empty,那么JSP容器会首先调用setBodyContent()和doInitBody()方法。然后在标签之间的内容执行完毕后,会接着调用public int doAfterBody() throws JspException方法。需要注意的是,JSP容器在调用setBodyContent()方法之前,首先会调用pageContext. pushBody()方法,在doAfterBody()方法返回了Tag.SKIP_BODY之后,JSP容器会调用pageContext.popBody()方法。以下是类中这几个方法的代码:
Java代码

   1. public BodyContent pushBody() { 
   2.     return (BodyContent) pushBody(null); 
   3. } 
   4.  
   5. public JspWriter pushBody(Writer writer) { 
   6.     depth++; 
   7.     if (depth >= outs.length) { 
   8.         BodyContentImpl[] newOuts = new BodyContentImpl[depth + 1]; 
   9.         for (int i=0; i<outs.length; i++) { 
  10.             newOuts[i] = outs[i]; 
  11.         } 
  12.         newOuts[depth] = new BodyContentImpl(out); 
  13.         outs = newOuts; 
  14.     } 
  15.  
  16.     outs[depth].setWriter(writer); 
  17.     out = outs[depth]; 
  18.  
  19.     // Update the value of the "out" attribute in the page scope 
  20.     // attribute namespace of this PageContext 
  21.     setAttribute(OUT, out); 
  22.  
  23.     return outs[depth]; 
  24. } 
  25.  
  26. public JspWriter popBody() { 
  27.     depth--; 
  28.     if (depth >= 0) { 
  29.         out = outs[depth]; 
  30.     } else { 
  31.         out = baseOut; 
  32.     } 
  33.  
  34.     // Update the value of the "out" attribute in the page scope 
  35.     // attribute namespace of this PageContext 
  36.     setAttribute(OUT, out); 
  37.  
  38.     return out; 
  39. } 

public BodyContent pushBody() {
    return (BodyContent) pushBody(null);
}

public JspWriter pushBody(Writer writer) {
    depth++;
    if (depth >= outs.length) {
        BodyContentImpl[] newOuts = new BodyContentImpl[depth + 1];
        for (int i=0; i<outs.length; i++) {
            newOuts[i] = outs[i];
        }
        newOuts[depth] = new BodyContentImpl(out);
        outs = newOuts;
    }

    outs[depth].setWriter(writer);
    out = outs[depth];

    // Update the value of the "out" attribute in the page scope
    // attribute namespace of this PageContext
    setAttribute(OUT, out);

    return outs[depth];
}

public JspWriter popBody() {
    depth--;
    if (depth >= 0) {
        out = outs[depth];
    } else {
        out = baseOut;
    }

    // Update the value of the "out" attribute in the page scope
    // attribute namespace of this PageContext
    setAttribute(OUT, out);

    return out;
}

    从以上代码可以知道,在调用了pageContext.pushBody()方法之后,out上的输出被重定向到BodyContent上了(BodyContent这个抽象类继承了JspWriter ),也就是说标签体的执行结果也被输出到BodyContent上了,这就是在doAfterBody()方法内可以通过 getBodyContent().getString()的到标签体输出的原因。



1.4 Simple Tag
    为了简化Tag的开发,从JSP2.0起引入了SimpleTag接口和SimpleTagSupport类。SimpleTag直接继承了JspTag,其定义如下:
Java代码

   1. public void doTag() throws  JspException, IOException; 
   2. public void setParent( JspTag parent ); 
   3. public JspTag getParent(); 
   4. public void setJspContext( JspContext pc ); 
   5. public void setJspBody( JspFragment jspBody ); 

public void doTag() throws  JspException, IOException;
public void setParent( JspTag parent );
public JspTag getParent();
public void setJspContext( JspContext pc );
public void setJspBody( JspFragment jspBody );

   为了访问标签体,SimpleTag中包含了setJspBody( JspFragment jspBody )方法,JSP容器会把标签体封装到JspFragment 后进行注入。在doTag()方法内,可以任意多次的调用getJspBody().invoke(Writer w)方法来执行标签体。在tld文件中,SimpleTag对应的body-content不可以设置成JSP。

   JSP2.0同时新增了DynamicAttributes接口为标签增加动态属性的功能。JSP容器会在调用doTag()方法前,调用其接口上的如下方法进行属性的注入:
Java代码

   1. void setDynamicAttribute(String uri, String localName, Object value) throws JspException 

void setDynamicAttribute(String uri, String localName, Object value) throws JspException



1.5 Tag File
    Tag File也是JSP2.0新增的主要功能之一,它允许开发人员使用JSP语法来制作标签。Tag File的扩展名为.tag或.tagx。假如Tag File 包含其他完整或片断的Tag File,建议扩展名为.tagf。Tag File通常被放置在WEB-INF/tags/目录下。Tag File的隐含对象(Implicit Object)有request,response,jspContext,session,application,out,config。Tag File中可以使用<jsp:doBody>和<jsp:invoke>这两个action元素。<jsp:doBody>可以用来执行标签体。<jsp:invoke>可以用来执行标签中JspFragment类型的属性。
    Tag File转译后的Java类继承自SimpleTagSupport,需要注意的是,在这个类的setJspContext( JspContext pc )方法中,传入的参数JspContext被org.apache.jasper.runtime.JspContextWrapper进行了包装。被包装的JspContext 上的跟Nested Variable同名的属性也会被保存到JspContextWrapper上。JspContextWrapper的setAttribute()方法会拦截对PAGE_SCOPE属性的设置:这些属性并不保存在被包装的JspContext上,而是保存在JspContextWrapper上。在执行标签内容之前,JSP容器会把JspContextWrapper上Nested 和 AT_BEGIN Variables拷贝到被包装的JspContext 的PAGE_SCOPE中。在执行完标签体之后,JSP容器会复原之前保存在JspContextWrapper上的Nested Variable到被包装的JspContext 上,同时拷贝AT_END Variables到被包装的JspContext 上。
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    jsp tag接口图

    **JSP Tag接口图**是JavaServer Pages(JSP)技术中的一个重要概念,它涉及到JSP自定义标签的开发和实现。在JSP中,标签库可以极大地提高代码的可读性和可维护性,而Tag接口是创建这些自定义标签的基础。本篇将深入...

    birt jsp tag

    BIRT中JSP Tag的使用 BIRT从2.2开始(最好采用2.2M6及以后版本),提供JSP tag的支持。 现在主要提供了以下5个JSP Tag: 1. viewer --------- 对应 frameset/run 模式,基于Ajax 2. report ---------- 对应 preview...

    javascript合并压缩的jsp tag实现

    JavaScript 合并压缩的 JSP Tag 实现是一个常见的前端优化技术,主要目的是为了减少网络请求次数,提升网页加载速度。在网页开发中,通常会有多份 JavaScript 文件,每份文件都对应一个网络请求,这会增加页面加载...

    jsp tag标签的使用

    在JSP中,tag标签是实现页面逻辑和视图分离的重要手段,提高了代码的可重用性和可维护性。本文将详细介绍JSP的tag标签及其使用方法。** 首先,我们要理解JSP中的tag标签分为两种类型:标准标签库(JSTL, JavaServer...

    dbform jsp tag框架

    "dbform jsp tag框架"是一个专为Java Web开发者设计的高效工具,它利用JSP标签(tag)技术,简化了界面与业务逻辑的交互,从而加速了开发进程。这个框架特别适合构建数据密集型的应用,如表单提交、列表展示等常见...

    ZK框架JSP TAG使用手册

    ### ZK框架JSP TAG使用手册 #### 一、前言与准备工作 ##### 新手入门:JSP与ZK 如果你是初次接触JSP(JavaServer Pages)或ZK框架,那么这份用户指南将为你提供一个很好的起点。JSP是一种用于生成动态网页的技术...

    Manning - JSP Tag Libraries.pdf

    《Manning - JSP Tag Libraries》这本书深入探讨了JavaServer Pages (JSP) 标签库这一核心主题,对于理解并有效利用JSP技术进行Web开发具有极高的价值。标签库是JSP中一种强大的工具,它允许开发者通过自定义的标签...

    Manning - JSP Tag Libraries.rar

    在"**Manning - JSP Tag Libraries**"这个资源中,我们将深入探讨JSP标签库的核心概念、使用方法及其在实际开发中的应用。 ### 1. JSP标准标签库 (JSTL) JSTL(JavaServer Pages Standard Tag Library)是Oracle...

    JSP Tag Libraries

    《JSP Tag Libraries》这本书由Gal Shachor、Adam Chace和Magnus Rydin共同编写,是一本深入探讨JavaServer Pages(JSP)标签库开发的专业书籍。JSP技术是Sun Microsystems公司推出的一种用于创建动态网页的技术,它...

    JSP2.0 Tag 使用

    在JSP2.0技术规范中,引入了一种新的标签机制,被称为Tag Files(标签文件),其主要目标是为了解决传统JSP页面中脚本元素的使用问题,提供一个更为简洁和高效的方式来进行页面动态内容的添加。开发者可以利用标签...

    JSP tag.ppt

    什么是Tag文件 Tag文件的结构 Tag文件的保存 Tag标记与Tag文件的使用 Tag文件中的常用指令 Tag标记的嵌套

    JSP_tag.rar_Eclipse_eclipse jsp t_jsp custom tag_自定义标签

    首先,创建一个新的动态Web项目,然后通过Lomboz的"New &gt; JSP Tag Library"向导创建标签库。向导会生成一个默认的TLD文件,我们需要在这个文件中定义我们的自定义标签。例如,我们可以定义一个名为`&lt;hello&gt;`的标签,...

    CTag.zip_JSP tag_This Is It

    CustomTags This applications clearly inplements custom tag and it use in jsp pages. And is very useful while developing jsp applications.

    java仿google模糊搜索框jsp的tag标签通用查询功能

    在这个项目中,开发者已经创建了一个基于JSP的Tag标签库,实现了这样一个通用的模糊搜索功能。 首先,让我们了解一下什么是JSP Tag标签。JSP Tag标签是JSP的一种扩展机制,它允许开发者创建自定义的、可重用的组件...

    超级封装的.tag标签分页、超级简化jsp内的分页代码、eclipse源码

    本资源提供了一种高效且简洁的分页解决方案,利用.tag标签技术来封装分页逻辑,使得在JSP页面中的实现变得简单易懂。 首先,我们来详细了解一下`.tag`标签。`.tag`文件是JSP标准标签库(JSTL)的一部分,用于创建...

    javax.servlet.jsp.tagext源码

    在Java服务器页面(JSP)技术中,`javax.servlet.jsp.tagext`包是核心组件之一,它提供了用于创建自定义标签库(Tag Libraries)的接口和类。自定义标签是JSP的一种强大特性,允许开发者将复杂的逻辑封装到可重用的...

    WAP 语言标签库 JAVA Jsp tag WAP WML XHTML

    同时支持WAP1.2 ,WAP2.0 ,PDA语言的自适应标签库,使用标签可以利用传入参数可以自由控制页面形态,适配成WML,XHTML,HTML页面.这样用标签库做出一套页面,就是三种同样内容的页面.对于无线内容的开发者,标签库可以减少...

    JSP自定义标签(一)_树形下拉选择菜单

    TLD(Tag Library Descriptor)文件是用来描述标签库中所有自定义标签的元数据。在这个文件中,定义了`SelectorTag`的属性、功能和如何在JSP页面中调用它。 #### 六、CSS代码的重要性 CSS(Cascading Style Sheets...

    JSP及WEB技术 中英文对照文献

    1 JSP简介 JSP(JavaServer Pages)是一种基于Java的脚本技术。是由Sun Microsystems公司倡导、许多公司参与... html) to insert Java program segment (Scriptlet) and JSP tag (tag), To form the JSP file(*jsp).

    jsp 定制标签(Custom Tag).docx

    要创建一个没有Body内容的自定义标签,你需要实现`javax.servlet.jsp.tagext.Tag`接口或继承`TagSupport`类。主要覆盖以下两个方法: - `doStartTag()`: 这个方法在遇到自定义标签时被调用。返回值决定了标签体...

Global site tag (gtag.js) - Google Analytics