文档章节

自定义标签的一些概念

肥猫钓鱼
 肥猫钓鱼
发布于 2014/11/18 14:00
字数 3272
阅读 33
收藏 1
点赞 0
评论 0

自定义标签基础知识 1.自定义标签(Custom Tag)概述

<!--[if !supportLists]-->(1)用户自定义的一种jsp标记。自定义标签将那些重复工作进行封装,从而提高了工程生产力,而且将具有共用特性的标签库应用于不同的项目中,体现了软件复用的思想。

<!--[if !supportLists]-->(2)当一个含有自定义标签的jsp页面被jsp引擎(Web容器)编译成servlet时,标签将被转化成对一个称为tag处理类的对象的操作。之后当JSP页面对应的servlet被执行时,jsp引擎就调用这些操作。

2.标签的形式

<前缀:标签名 属性名1=值1属性名2=值2 …>标签主体</前缀:标签名>

一个标签可以没有属性或者没有主体,也可以同时没有属性和主体。没有主体的标签可以简写成这样的形式:<前缀:标签名 属性名1=值1 …/>、<前缀:标签名/>。 3.自定义标签的优点

<!--[if !supportLists]-->(1)分离了程序逻辑和表示逻辑。

<!--[if !supportLists]-->(2)将Java代码从HTML中剥离,便于美工维护页面。

<!--[if !supportLists]-->(3)减少了JSP页面中的脚本,减少了维护成本。

<!--[if !supportLists]-->(4)提供了可重用的功能组件。

4.自定义标签库(Custom Tag library)

由一系列功能相似、逻辑上互相联系的自定义标签构成的集合称为标签库。 5.创建自定义标签的方式

(1)Java类文件方式。

(2)标签文件方式。

标签文件是一个扩展名为.tab的文件,它必须存储在Web应用程序的WEB-INF目录中。标签文件的作用类似标签处理文件,它是一个包含一些内容或JSP代码的要重用的JSP片段。在JSP页面遇到自定义标签时,它会转到标签文件以执行标签定义。不需要一个单独的标签库描述符,因为标签文件包含自定义标签的完整实现。

Java类文件方式创建和使用一个自定义标签库的基本步骤有如下几步。

(1)创建标签的处理类(Tag Handle Class)。定义标签的行为,并在JSP引擎遇到自定义标签时调用执行。标签处理类是一个Java类,这个类继承了TagSupport或者扩展了SimpleTag接口,通过这个类可以实现自定义JSP标签的具体功能。

(2)创建标签库描述文件TLD(Tag Library Descrptor File)。描述标签库的XML文档,向JSP引擎提供有关自定义标签的标签处理程序的信息。

(3)在web.xml文件中声明TLD的位置。

(4)在JSP文件中用taglib指令引入标签库。

(5)在JSP中使用标签库标签。 6.创建标签的处理类

(1)传统标签处理器在javax.servlet.jsp.tagext包中的接口和类,如图8-1所示。

<!--[if !vml]--><!--[endif]-->

图8-1 传统标签的接口和类

我们要写的自定义标签处理类主要继承自TagSupport、BodyTagSupport这两个类。通过继承这两个类,只需要重新定义那些需要自定义的行为的方法,从而简化了标签处理程序的开发。

(2)简单标签处理器javax.servlet.jsp.tagext包中的接口和类。我们要写的自定义标签处理类继承自SimpleTagSupport类,重写doTag()方法。这是在JSP2.0新规范中增加的类,这个类实现自SimpleTag接口,之所以称其为“简单”是指它相对于传统标签处理器实现任务要简单得多。

(3)TagSupport类。TagSupport类并不能对标签主体的内容做任何处理,您所能决定的只是是否显示主体的内容。

① 生命周期

当JSP容器在解释JSP页面时,如果碰到自定义标签,将利用“标签处理类”建立一个“标签处理对象”。在建立“标签处理对象”的过程中,JSP容器会根据自定义标签的属性值来初始化“标签处理对象”的属性。

首先,JSP容器会运行doStartTag()方法内的程序代码,然后根据此方法的返回值决定后续动作。如果返回SKIP_BODY,表示要求JSP容器忽略标签主体的内容;如果返回EVAL_BODY_INCLUDE,表示要求JSP容器要显示标签主体的内容,然后运行doAfterBody()方法。

如果doAfterBody()方法传回EVAL_BODY_AGAIN,表示要求JSP容器再次显示标签主体的内容,如果返回SKIP_BODY,JSP容器将会运行doEndTag()方法。

最后,JSP容器会运行doEndTag()方法内的程序代码,并根据此方法的返回值决定后续动作:如果返回SKIP_PAGE,JSP容器会运行release()方法,然后忽略自定义标签以后的JSP内容;如果返回EVAL_PAGE,JSP容器会先运行release()方法,然后运行自定义标签以后的JSP内容。

② 生命周期主要方法

● doStartTag()方法可返回的值有SKIP_BODY,忽略标签主体的内容(此方法的预设返回值);VAL_BODY_INCLUDE,表示要求JSP容器要显示标签主体内容。

● doAfterBody()方法可返回的值有以下几项。

● SKIP_BODY:要求JSP容器忽略主体内容,进入标签处理程序的下一步工作(此方法的预设返回值)。

● EVAL_BODY_AGAIN:要求JSP容器再次显示标签主体内容。

● doEndTag()方法可返回的值有以下几项

● SKIP_PAGE:忽略自定义标签以后的JSP网页内容。

● EVAL_PAGE:运行自定义标签以后的JSP网页内容(此方法的预设返回值)。

● release():释放标签处理对象所占用的系统资源。

(4)BodyTagSupport类。

① 生命周期

BodyTagSupport与TagSupport的区别主要是标签处理类是否需要读取标签体的内容和改变标签体返回的内容,如果不需要交互的就用TagSupport,否则就用BodyTagSupport。

这里需要注意的是TagSupport也可以有体,如果将TagSupport理解成是没有体的标签,而将BodyTagSupport理解成是有体的标签就错了。当然用TagSupport实现的标签,都可以用BodyTagSupport来实现,道理很简单,因为BodyTagSupport继承了TagSupport。

② 生命周期主要方法

● doStartTag() 方法可返回的值有SKIP_BODY,表示要求JSP容器忽略主体内容;

EVAL_BODY_INCLUDE,表示要求JSP容器要显示标签主体内容;EVAL_BODY_BUFFERED 表示JSP容器会将标签主体的处理结果建立成一个BodyContent对象(此方法的预设返回值)。

● setBodyContent()方法会设置BodyContent对象的一些属性,包括标签主体的内容和在处理标签过程中要输出至response的数据对象。

● doInitBody()方法在第一次处理标签主体内容时,它将对主体进行初始化的工作。

● doAfterBody()方法可返回的值有SKIP_BODY,表示要求JSP容器忽略主体,进入下一步的处理工作;EVAL_BODY_AGAIN,表示要求JSP容器再次处理标签主体。

● doEndTag()方法可返回的值有SKIP_PAGE,表示忽略自定义标签以后的JSP网页内容; EVAL_PAGE,表示运行自定义标签以后的JSP网页内容。

● release()方法释放标签处理对象所占用的系统资源。

(5)SimpleTagSupport类。

生命周期事件有以下几种。

● 当JSP容器遇到标记时,将标签处理类的默认构造方法建立一个标签处理实例。注意必须为每个标记都创建一个新的实例,这很重要。

● 在标记处理程序中调用setJspContext()和setParent()方法。如果传递的值是“null”,则不需要调用setParent()方法。在使用标记文件的情况下,创建一个JspContext包装,以便标记文件看上去具有其本身的页面范围。调用getJspContext()必须返回所包装的JspContext。

● 容器为每个标记所定义的属性,同时也需要提高set方法,set方法是用来让外界设置属性的值,其顺序是它们出现在JSP页或标记文件中的顺序。如果属性值是表达式语言的表达式或运行时表达式,则它首先被赋值,然后被传递到设置器;另一方面,如果属性为动态属性,则调用setDynamicAttribute()。

● 由容器调用setJspBody()方法,将该标记的主体设置为JspFragment;如果标记被声明为具有空的值,则将null值传递到setJspBody()。

● 由容器调用doTag()方法。所有的标记逻辑、迭代、主体赋值等都在该方法中发生。

● 在doTag()方法返回后,所有的变量被同步。 7.撰写标签处理类

你所撰写的标签处理类应该具备下列特性:

● 承TagSupport类或BodyTagSupport类或SimpleTagSupport类;

● 对自定义标签的属性声明相对应的变量,并提供一个setXXX()方法;

● doStartTag()、doAfterBody()或doEndTag()方法(或doTag()方法)内撰写Java程序代码,实现自定义标签欲提供的功能。

示例如下: [java] view plaincopy

Welcome.java  
  
package com.mapgis.vfd.taglib;  
  
  
import javax.servlet.jsp.tagext.BodyTagSupport;  
  
import javax.servlet.jsp.tagext.BodyContent;  
  
import javax.servlet.jsp.JspWriter;  
  
import java.io.IOException;  
  
  
public class Welcome extends BodyTagSupport {  
  
    public int doAfterBody() {  
  
        try {  
  
         //获得标签体的内容  
  
          BodyContent bodyContent = super.getBodyContent();  
  
         String bodyString = bodyContent.getString();  
  
          //获取输出流对象  
  
         JspWriter out = bodyContent.getEnclosingWriter();  
  
        out.print(bodyString.toUpperCase());  
  
        bodyContent.clear();  
  
        } catch (IOException e) {  
      System.out.println("BodyContentTag.doAfterBody() 中出现错误" + e.getMessage());  
  
       e.printStackTrace();  
  
       }  
  
      return this.SKIP_BODY;  
  
    }  
  
}  

[xhtml] view plaincopy

8.创建标签库描述文件  
标签库描述文件(Tag Library Discriptor,TLD)是一份标准的XML文件,用来记录一个标签库内拥有哪些标签?每个标签包含哪些属性?取得这些信息后,JSP容器才能正确地处理并运行JSP所包含的自定义标签。以下是一个JSP2.0规范的TLD:  
  
weclome.tld  
  
<?xml version="1.0" encoding="UTF-8"?>  
  
<!-- 标签库描述符 -->  
  
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"  
  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  
  
    version="2.0">  
  
    <!-- 此标签库的一个描述 -->  
  
    <description>A tag library exercising SimpleTag handlers.</description>  
  
        <!-- 此标签库的版本,由程序设计师自行决定(必须) -->  
  
    <tlib-version>1.0</tlib-version>  
  
        <!-- 定义一个简短的名称(必须)主要由工具使用 -->  
  
    <short-name>SimpleTagLibrary</short-name>  
  
    <!-- 定义该标签库的唯一uri名(在taglib指令中使用) -->  
  
    <uri>/SimpleTagLibrary</uri>  
  
      
  
    <tag><!-- 定义每个标签的特性 -->  
  
    <description>body content to Upper</description><!-- 描述 -->  
  
        <name>simpletag</name> <!-- 自定义标签的名称 -->  
  
        <tag-class>xmh.comchapter11.Welcome</tag-class> <!-- 此标签对应的处理类 -->  
  
        <body-content>scriptless</body-content><!-- 定义标签主体的种类:指定标签的格式,empty表示标签没有标签主体;JSP表示标签的标签体中可以包含JSP代码;scriptless表示标签主体中可以包含EL表达式和JSP的动作元素,但不能包含JSP的脚本元素;tagdependent表示标签的标签主体交由标签本身去解析处理。如果指定为它,那么你在标签体中所写的任何代码都会原封不动地传给标签处理器,而不是传递执行的结果。 -->  
  
        <attribute>  
  
          <name>attrName</name> <!-- 此属性的名称 -->  
  
          <required>false</required> <!-- 此属性是否为必要:true | false -->  
  
          <rtexprvalue>true</rtexprvalue><!-- 属性值是否可以在JSP运行时期动态产生:true | false -->  
  
        </attribute>  
  
    </tag>  
  
</taglib>  
  
9.在web.xml文件中声明TLD的位置  
<?xml version="1.0" encoding="UTF-8"?>  
  
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"   
  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">  
  
......  
  
<jsp-config>  
  
    <taglib>  
  
      <!-- 指定TLD文件所对应的URI -->  
  
      <taglib-uri>/mytag</taglib-uri>  
  
      <!-- 指定TLD文件的存放路径 -->  
  
      <taglib-location>/WEB-INF/tlds/weclome.tld</taglib-location>  
  
    </taglib>  
  
  </jsp-config>  
  
</web-app>  
  
注意在JSP2.0规范中可以不用声明TLD的位置,因为容器开始建立<uri>和TLD映射时,会首先在web.xml中查找,看是否有<taglib>项,如果确实有,就会使用这些设置来帮助建立映射。否则会在WEB-INF目录以及它的tlds子目录(还可以是jar文件中)下查找TLD文件,然后自动建立TLD文件和<uri>名之间的映射关系。  
  
10.在JSP文件中用taglib指令引入标签库  
<%@ taglib uri="/mytag" prefix="my" %>  
  
11.在JSP中使用标签库标签  
<my:simpletag>Hello,World!</my:simpletag>  
  
12.自定义JSP标签的处理过程  
<!--[if !supportLists]-->(1)在JSP中引入标签库:<% @ taglib prefix="taglibprefix" uri="tagliburi" %>。  
  
<!--[if !supportLists]-->(2)在JSP中使用标签库标签:<prefix : tagname attribute="tagattribute">。  
  
<!--[if !supportLists]-->(3)Web容器根据第二个步骤中的prefix,获得第一个步骤中声明的taglib的uri属性值。  
  
<!--[if !supportLists]-->(4)Web容器根据uri属性在web.xml找到对应的<taglib>元素。  
  
<!--[if !supportLists]-->(5)从<taglib>元素中获得对应的<taglib-location>元素的值。  
  
<!--[if !supportLists]-->(6)Web容器根据<taglib-location>元素的值从WEB-INF/目录下找到对应的.tld文件。  
  
<!--[if !supportLists]-->(7)从.tld文件中找到与tagname对应的<tag>元素。  
  
<!--[if !supportLists]--><!--[endif]-->(8)从<tag>元素中获得对应的<tag-class>元素的值。  
  
<!--[if !supportLists]-->(9)Web容器根据<tag-class>元素的值创建相应的标签处理类的实例。  
  
<!--[if !supportLists]-->(10)Web容器调用这个实例的doStartTag/doAfterBody/doEndTag方法完成相应的处理。   

本文转载自:http://blog.csdn.net/hbzyaxiu520/article/details/5207960#t1

共有 人打赏支持
肥猫钓鱼
粉丝 1
博文 29
码字总数 9287
作品 0
深圳
程序员
三天学会HTML5 之第一天

引言 HTML5 一直是非常热门的话题,因此此系列文章主要从一些基本功能开始讲起,逐步深入了解HTML5的新概念。 首先了解一些基本的术语和概念。 SGML, HTML,XML三者之间的区别 Doc类型是什么 ...

葡萄城控件技术团队 ⋅ 2016/02/02 ⋅ 0

thinkphp3.2的行为

行为是什么 行为扩展官方文档 行为(Behavior)是一个比较抽象的概念,你可以想象成在应用执行过程中的一个动作或者处理,在框架的执行流程中,各个位置都可以有行为产生,例如路由检测是一个...

oneboi ⋅ 2016/12/20 ⋅ 0

Java Server Faces (JSF) 页面转换与验证(一)

由于primefaces在国内使用的并不是太多,因此,国内对jsf做系统、详细的介绍的资料很少,即使有一些资料,也仅仅是对国外资料的简单翻译或者是仅仅讲表面现象(皮毛而已),它们的语句甚至还...

码上中国博客 ⋅ 2015/02/03 ⋅ 0

【翻译】如何创建Ext JS暗黑主题之二

原文:How to Create a Dark Ext JS Theme– Part 2 我已经展示了如何去开发一个精致的暗黑主题,看起来就像Spotify。在本文的第一部分,了解了Fashion、Sencha Inspector、主题和变量。在第...

tianxiaode2008 ⋅ 2015/07/22 ⋅ 0

Dubbo源码-Dubbo是如何随心所欲自定义XML标签的

叨叨 今天考虑了很久要不要写这篇文章。 距离《Dubbo源码》系列的开篇到现在已经快两个月时间了。当时是想着工作上的RPC框架使用存在一些让人头疼的问题,就来看看Dubbo给出了一套什么样的解...

Jackie_Zheng ⋅ 05/20 ⋅ 0

Smarty前端模板引擎 - 我看过的PHP开源框架

Smarty Smarty可以说是我接触PHP这门语言用到的第一个开源框架,当时在Smarty的帮助下,很好地完成了项目的开发,也很好地遵循了MVC的模式。但是到了后来,慢慢地发现,很多人都很熟悉Smart...

暗夜在火星 ⋅ 2014/12/25 ⋅ 0

一步步编写PHP的Framework(一)

框架这个概念可能一开始就吓坏了很多PHP的Coder,其实你只要把一个Framework想明白了,其实也没啥,只是别人功能更复杂,细节考虑的更多,代码质量更高。 框架最重要的一个文件为入口文件,基...

NateHuang ⋅ 2016/07/27 ⋅ 0

新一代火狐 (FireFox) 界面将引入OS概念

开源浏览器Firefox 4.0中添加的“Tab Candy”技术将使得火狐的界面具备类似操作系统的特征,在多任务处理、共享等方面实现突破。 据Mozilla实验室高级工程师拉斯·金透露,很多用户喜欢首先打...

红薯 ⋅ 2010/07/31 ⋅ 5

JSP自定义标签

由于之前学习JSP时只是了解可以自定义JSP标签,但从没自己定义和使用过,具体怎么定义和使用不太清楚。最近,在项目过程中遇到一些问题,比如页面中接收或传递的某个值需要进行其他处理,而这...

IceRainYWC ⋅ 2013/11/20 ⋅ 0

struts2一些概念介绍和标签的使用

依赖注入 模块包含 struts.xml的模块包含格式 OGNL 对象导航语言 有个超大的好处就是根据对象访问属性,避免混乱。 OGNL标签分为:data tags和 control tags 一、数据标签 property标签 获取...

ke_ry ⋅ 2016/12/30 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周六乱弹 —— 假如你被熊困到树上

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《如果写不出好的和弦就该在洒满阳光的钢琴前一起吃布丁》 《如果写不出好的和弦就该在洒满阳光的钢琴前一起吃布丁》- 谢...

小小编辑 ⋅ 23分钟前 ⋅ 2

vbs 取文件大小 字节

dim namedim fs, s'name = Inputbox("姓名")'msgbox(name)set fs = wscript.createobject("scripting.filesystemobject") 'fs为FSO实例if (fs.folderexists("c:\temp"))......

vga ⋅ 今天 ⋅ 1

高并发之Nginx的限流

首先Nginx的版本号有要求,最低为1.11.5 如果低于这个版本,在Nginx的配置中 upstream web_app { server 到达Ip1:端口 max_conns=10; server 到达Ip2:端口 max_conns=10; } server { listen ...

算法之名 ⋅ 今天 ⋅ 0

Spring | IOC AOP 注解 简单使用

写在前面的话 很久没更新笔记了,有人会抱怨:小冯啊,你是不是在偷懒啊,没有学习了。老哥,真的冤枉:我觉得我自己很菜,还在努力学习呢,正在学习Vue.js做管理系统呢。即便这样,我还是不...

Wenyi_Feng ⋅ 今天 ⋅ 0

博客迁移到 https://www.jianshu.com/u/aa501451a235

博客迁移到 https://www.jianshu.com/u/aa501451a235 本博客不再更新

为为02 ⋅ 今天 ⋅ 0

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 今天 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 今天 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部