`
rayn115
  • 浏览: 68835 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

jsp2.0自定义标签Tag

    博客分类:
  • Java
阅读更多

JSP2.0 中,对于自定义的标签有两种实现方法,实现接口或者继承现有的类

如下图,标注蓝色的是接口,其它是标签类(SimpleTagSupport 只在JSP2.0 中才有)

 

tag2.JPG  

在以上接口和类中,定义了一些静态常量,如下:

Tag 中定义:

SKIP_BODY = 0;          // 不处理标签体,直接调用doEndTag() 方法

EVAL_BODY_INCLUDE = 1;   // 解析标签体, 但绕过 doInitBody () setBodyContent () 方法

SKIP_PAGE = 5;          // 不解析标签后面的JSP 内容

EVAL_PAGE = 6;          // 解析标签后, 继续解析标签后面的JSP 内容

 

IterationTag 中定义:

EVAL_BODY_AGAIN = 2;

 

BodyTag 中定义:

EVAL_BODY_TAG = 2;          // deprecated

EVAL_BODY_BUFFERED = 2;    //

 

特别的,对于EVAL_BODY_AGAINEVAL_BODY_BUFFERED

doAferBody 中返回SKIP_BODY ,表示终止标记正文处理 ;若返回的是 EVAL_BODY_BUFFERED ,将会再一次调用 doAferBody 方法,重新处理标记正文,直到返回SKIP_BODY 为止。  //

 

TagSupport 默认doStartTag()/doAfterBody() 返回SKIP_BODY

BodyTagSupport 默认doStartTag() 返回EVAL_BODY_BUFFERED / doInitBody() 什么也不做 /doAfterBody() 返回SKIP_BODY

下面是自定义tag 的执行过程(由上至下),对于以上各常量的实际运用为:

注意其中的 doInitBody/setBodyContent 方法在自定义标签实现了 BodyTag 接口或继承BodyTagSupport 才可以使用

Tag 方法

可返回的静态常量

doStartTag

SKIP_BODY EVAL_BODY_INCLUDE

EVAL_BODY_AGAIN/EVAL_BODY_BUFFERED

doInitBody

做标签一些初始化工作,无返回值

setBodyContent

doInitBody 之后执行,使用setBodyContent 得到JSP 页面中标签体之间内容

doAfterBody

最终必须返回SKIP_BODY ,否则可能导致OutOfMemoryError ,可参考上面

doEndTag

SKIP_PAGE/EVAL_PAGE

 

示例代码如下:

public int doAfterBody() throws JspException {

  try {

   this.pageContext.getOut().write("<br>");

  } catch (IOException e) {

      e.printStackTrace();

  }

  if(cou>1){

   cou--;

   return this.EVAL_BODY_AGAIN;

  }else{

   return this.SKIP_BODY;   // 最终必须返回SKIP_BODY

  }

  }

 

自定义标签的开发包括:

1.  开发标签的处理程序(java 类)

2.  .tld 文件中指定标签使用的类

3.  web.xml 中指定JSP 中使.tld( 标签库描述文件) 文件的位置。

 

.tld 文件中

<tag>

    <name>out</name>

    <tag-class>org.apache.taglibs.standard.tag.el.core.OutTag</tag-class>

<body-content >JSP</body-content>

<attribute>

        <name>value</name>

        <required>true</required>

        <rtexprvalue >false</rtexprvalue>

  </attribute>

  </tag>

 

body-content

根据web-jsptaglibrary_2_0.xsd (位于servlet-api.jar 包($TOMCAT_HOME\common\lib )中的\javax\servlet\resources 下,其中web.xml 验证时所需要的xsd 文件都位于此resources 目录下), body-content 的值有下面4 种:

<xsd:enumeration value="tagdependent "/>

    <xsd:enumeration value="JSP "/>

    <xsd:enumeration value="empty "/>

    <xsd:enumeration value="scriptless "/>

 

 

tagdependent 标签体内容 直接被写入BodyContent ,由自定义标签类来进行处理,而不被JSP 容器解释

如下:

<test:myList>

select name,age from users

</test:myList>

 

JSP 接受所有JSP 语法,如定制的或内部的tagscripts 、静态HTML 、脚本元素、JSP 指令和动作。如:

<my:test>

    <%=request.getProtocol()%>      //

</my:test>

具体可参考后面附源码。

 

empty 空标记,即起始标记和结束标记之间没有内容。

下面几种写法都是有效的,

<test:mytag />

<test:mytag uname="Tom" />

<test:mytag></test:mytag>

 

scriptless 接受文本、ELJSP 动作。如上述 使用<body-content> scriptless </body-content> 报错 ,具体可参考后面附源码。

 

rtexprvalue:

由请求时表达式来指定属性的值,默认为false ,如下必须设置为true

<test:welcome uname="<%=request.getParameter("username") %>" />

 

 

body-content JSP/scriptless 时标签体可以接受的代码(jasper-compiler.jar $TOMCAT_HOME\common\lib )中 \org\apache\jasper\compiler\Parser.java 中):

JSP:

private void parseElements(Node parent)

        throws JasperException

    {

        if( scriptlessCount > 0 ) {

            // vc: ScriptlessBody

            // We must follow the ScriptlessBody production if one of

            // our parents is ScriptlessBody.

            parseElementsScriptless( parent );

            return;

        }

       

        start = reader.mark();

        if (reader.matches("<%--")) {

            parseComment(parent);

        } else if (reader.matches("<%@")) {

            parseDirective(parent);

        } else if (reader.matches("<jsp:directive.")) {

            parseXMLDirective(parent);

        } else if (reader.matches("<%!")) {

            parseDeclaration(parent);

        } else if (reader.matches("<jsp:declaration")) {

            parseXMLDeclaration(parent);

        } else if (reader.matches("<%=")) {

            parseExpression(parent);

        } else if (reader.matches("<jsp:expression")) {

            parseXMLExpression(parent);

        } else if (reader.matches("<%")) {

            parseScriptlet(parent);

        } else if (reader.matches("<jsp:scriptlet")) {

            parseXMLScriptlet(parent);

        } else if (reader.matches("<jsp:text")) {

            parseXMLTemplateText(parent);

        } else if (reader.matches("${")) {

            parseELExpression(parent);

        } else if (reader.matches("<jsp:")) {

            parseStandardAction(parent);

        } else if (!parseCustomTag(parent)) {

            checkUnbalancedEndTag();

            parseTemplateText(parent);

        }

}

Scriptless:

private void parseElementsScriptless(Node parent)

        throws JasperException

    {

        // Keep track of how many scriptless nodes we've encountered

        // so we know whether our child nodes are forced scriptless

        scriptlessCount++;

       

        start = reader.mark();

        if (reader.matches("<%-- ")) {

            parseComment(parent);

        } else if (reader.matches("<%@ ")) {

            parseDirective(parent);

        } else if (reader.matches("<jsp:directive. ")) {

            parseXMLDirective(parent);

        } else if (reader.matches("<%!")) {

            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );

        } else if (reader.matches("<jsp:declaration")) {

            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );

        } else if (reader.matches("<%=")) {

            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );

         } else if (reader.matches("<jsp:expression")) {

            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );

        } else if (reader.matches("<%")) {

            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );

        } else if (reader.matches("<jsp:scriptlet")) {

            err.jspError( reader.mark(), "jsp.error.no.scriptlets" );

        } else if (reader.matches("<jsp:text ")) {

            parseXMLTemplateText(parent);

        } else if (reader.matches("${ ")) {

            parseELExpression(parent);

        } else if (reader.matches("<jsp: ")) {

            parseStandardAction(parent);

        } else if (!parseCustomTag(parent)) {

            checkUnbalancedEndTag();

            parseTemplateText(parent);

        }

       

         scriptlessCount--;

}

 

由上面可以看出,局限性比较小,在body-content 可以使用 Scriptless 的地方都可以用 JSP 代替,反之则不可。

(转自: http://www.blogjava.net/xiaodaoxiaodao/archive/2007/01/05/103438.html)

分享到:
评论

相关推荐

    JSP2.0技术手册pdf(带示例源码).zip

    书名:JSP 2.0 技术手册(电子书) 格式:PDF 出版:电子工业出版社 作者:林上杰、林康司 本书图文并茂,以丰富的实例为引导,全面介绍了主流的 Java Web 开发技术—— JSP 2.0,重点介绍Java在展示层的两项重要技术...

    Tag的使用<JSP 2.0新特性>

    这是一个Tag文件使用的一个实例...它的是简化了自定义标签,呵呵...不准确.

    JSP 自定义标签

    JSP 2.0规范中引入Simple Tag Handlers来编写这些自定义标记。 你可以继承SimpleTagSupport类并重写的doTag()方法来开发一个最简单的自定义标签。 创建”Hello”标签 接下来,我们想创建一个自定义标签叫作,标签...

    JSP自定义标签入门学习

    本文为大家分享了JSP... JSP 2.0规范中引入Simple Tag Handlers来编写这些自定义标记。你可以继承SimpleTagSupport类并重写的doTag()方法来开发一个最简单的自定义标签。 2.开发自定义标签 下面的步骤建立一个自定

    java自定义标签

    java 自定义标签的解读: 书写tld文件《此tld文件写上文件的头,版本号,和页面的访问短名称》。 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;taglib version="2.0" xmlns:xsi=...

    自定义日历标签

    网页上显示日历,自定义的标签 !DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"&gt; &lt;tlib -version&gt;1.0 &lt;jsp -...

    JavaWeb标签应用开发

    JSTL(JSP Standard Tag Library ,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。JSTL只能运行在支持JSP1.2和Servlet2.3规范的容器上,如tomcat 4.x。在JSP 2.0中也是...

    JSP高级编程

    本书从最基础的JSP开发开始,循序渐进地介绍了JSP 开发技术,并涵盖了许多高级主题,如需要在企业级Web应用中使用的特性—Enterprise JavaBeans、JDBC 2.0、数据库连接池和自定义标签库。本书既适合初学者阅读,也...

    Spring 2.0 开发参考手册

    2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@...

    struts2 标签库 帮助文档

    &lt;%@ taglib prefix="s" uri="/struts-tags" %&gt; 就能使用struts2.0的标签库 下面就介绍每个标签的具体应用实例说明:按字母排列 A: 1. 2. &lt;s:a href=""&gt;&lt;/s:a&gt;-----超链接,类似于html里的&lt;a&gt;&lt;/a&gt; 3. ...

    java视频教程Day01 免费

    32. Java Standard Tag Library (标准标签库) 33. Expression Language(表达式语言) 34. Expression Language(表达式语言) 35. 使用Java WEB技术编写网页QQ J2EE 框架部分 36. Eclipse工具使用 37. ...

    J2EE面试题

    a) Tag File是JSP2.0新增的功能 b) Tag File是JSP1.2增的功能 c) Tag File 可以让网页开发人员直接使用JSP语法制作标签 d) Tag File的扩展名可以 .tag 参考答案 b 13) 关于Servlet Filter,下列说法正确的有...

    spring chm文档

    14.2.2. 'Plain-old' JSPs versus JSTL 'Plain-old' JSP与JSTL 14.2.3. 帮助简化开发的额外的标签 14.3. Tiles 14.3.1. 需要的资源 14.3.2. 如何集成Tiles 14.4. Velocity和FreeMarker 14.4.1. 需要的资源 ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的...

    Spring API

    2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...

    Spring中文帮助文档

    14.2.2. 'Plain-old' JSPs versus JSTL 'Plain-old' JSP与JSTL 14.2.3. 帮助简化开发的额外的标签 14.3. Tiles 14.3.1. 需要的资源 14.3.2. 如何集成Tiles 14.4. Velocity和FreeMarker 14.4.1. 需要的资源 ...

    GoodProject Maven Webapp.zip

    JSP技术有点类似ASP技术,它是在传统的网页HTML(标准通用标记语言的子集)文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在...

    JAVA上百实例源码以及开源项目

    Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接与浏览,Java源码下载 1个目标文件 摘要:Java源码,网络相关,HTTP  Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件...

    JAVA上百实例源码以及开源项目源代码

    Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接与浏览,Java源码下载 1个目标文件 摘要:Java源码,网络相关,HTTP  Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件...

Global site tag (gtag.js) - Google Analytics