Tag接口

任何一个标签都对应着一个java类,该类必须实现Tag接口,JSP遇到一个标签后后,将通过一个tld文件查找该标签的实现类,并运行该类的相关方法

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

public class TagTest implements Tag {
      private Tag parent;
      private PageContext pageContext;

      @Override
      public int doEndTag() throws JspException{  //标签结束时执行
             JspWriter out =pageContext.getOut();
             try{
                    out.println("……");
             }catch(IOExceptione){
                    throw new JspException(e);
             }
             return EVAL_PAGE;
      }

      @Override
      public int doStartTag() throwsJspException {  //标签开始时执行
             return SKIP_BODY;
      }

      @Override
      public Tag getParent() {
             // TODO Auto-generated method stub
             return null;
      }

      @Override
      public void release() {
             // TODO Auto-generated method stub

      }

      @Override
      public void setPageContext(PageContextarg0) {
             // TODO Auto-generated method stub

      }

      @Override
      public void setParent(Tag arg0) {
             // TODO Auto-generated method stub

      }

}

doStartTag方法可以返回两种参数,如果为SKIP_BODY,表示标签体内的内容不被输出,如果为EVAL_BODY_INCLUDE,则执行标签体内的代码

doEndTag也可以返回两种参数,如果为SKIP_PAGE,表示不执行标签后面的内容。如果为EVAL_PAGE,则执行标签后面的内容

此类中有两个属性,parent和pageContext,parent为该标签的父标签(或者是上一层的标签),pageContext为运行该标签的JSP页面,这两个参数都是JSP在运行时通过setter方法注射进去的

Tag实现类有了,还需要tld文件(Tag Library Descriptor)

<?xml version="1.0" ecoding="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                 web-jsptaglibrary_2_0.xsd
      version="2.0">

      <tlibversion>1.0</tlibversion>
      <jspversion> 1.1</jspversion>
      <shortname>tagname</shortname>
      <uri>http://www.clf.com/tags</uri>
      <info>A simple tag test</info>

<tag>
      <name>tagname</name>
      <tagclass>com.chen.tags.TagTest</tagclass>
      <bodycontent>JSP</ bodycontent>
      <info>tag information</info>
</tag>

</taglib>

shortname也就是推荐使用的prefix,uri就是引用这个标签库时使用的uri

bodycontent为标签体的限制,有三种取值

empty:不允许有标签体的存在,如果有会抛出异常

JSP:允许有标签体存在,可以为JSP代码

tagdependent:允许有标签体存在,但是标签里的JSP代码不会被执行

如果tld文件位于/WEB-INF/下面,Tomcat会自动加载;如果位于其他位置,可以在web.xm中配置

<jsp-config>
      <taglib>
             <taglib-uri> http://www.clf.com/tags</taglib-uri>
             <taglib-location>/WEB-INF/taglib.tld</taglib-location>
      </taglib>
</jsp-config>

TagSupport

多数情况下不需要直接实现Tag接口,使用TagSupport类就可以了,此类是java提供的一个模板类,一般来说,只需要实现doStartTag方法和doEndTag方法就可以了

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class Tagtest extends TagSupport {
      private int num1;
      private int num2;

      @Override
      public int doEndTag() throws JspException{
             try {
             this.pageContext.getOut().println("两数相加等于:"+(num1+num2));
             } catch (Exception e) {

             }
             return EVAL_PAGE;
      }

      @Override
      public int doStartTag() throwsJspException {
             return super.doStartTag();
      }

      public int getNum1() {
             return num1;
      }

      public void setNum1(int num1) {
             this.num1 = num1;
      }

      public int getNum2() {
             return num2;
      }

      public void setNum2(int num2) {
             this.num2 = num2;
      }

}

配置文件

<tag>
      <name>add</name>
      <tagclass>com.chen.tags.TagTest</tagclass>
      <bodycontent>JSP</bodycontent>
      <info>tag information</info>
      <attribute>
             <name>num1</name>
             <required>true</required >
             <rtexprvalue>true</rtexprvalue >
      </attribute>
      <attribute>
             <name>num2</name>
             <required>true</required >
             <rtexprvalue>true</rtexprvalue >
      </attribute>
</tag>

name代表属性的名字,required代表是否是必需的,rtexprvalue代表此属性是否允许使用EL表达式

以上这个标签这样使用:

<taglib:add num1=”2” num2=”3”/>

则页面会输出2和3 的相加之和

BodyTagSupport

BodyTagSupport是Tag接口的子类,专门处理带标签体的标签

public class ToLowerCaseTag extends BodyTagSupport{
      public int doEndTag throws JspException{
             //获取标签体内的代码
             String contend = this.getBodyContent().getString();
      try{
             this.pageContent.getOut().println(content.toLowerCase());
      }catch(Exception e){   }
             return EVAL_PAGE;
      }
}

只要在setBodyContent()方法之后被调用的方法中,都可以使用getBodyContent()方法获取标签体的内容,一般为doAfterBody()或者doEndTag()

BodyTagSupport的执行流程如下:

1.当容器创建一个新的标签实例后,通过setPageContext来设置标签的页面上下文.

2.使用setParent方法设置这个标签的上一级标签,如果没有上一级嵌套,设置为null.

3.设置标签的属性,这个属性在标签库描述文件中定义,如果没有定义属性,就不调用此类方法.

4.调用doStartTag方法,这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,当返回EVAL_BODY_INCLUDE时,就计算标签的body,如果返回SKIP_BODY,就不再计算标签的body,如果为EVAL_BODY_BUFFERED,则不会输出,而是将标签体内容通过setBodyContent()方法注射到标签类中,然后就可以使用getBodyContent()取得标签体的内容

5.调用setBodyContent设置当前的BodyContent.

6.调用doInitBody,如果计算BodyContent时需要进行一些初始化,就在这个方法中进行.

7.每次计算完Body后调用doAfterBody,如果返回EVAL_BODY_AGAIN,表示继续计算一次Body,直到返回SKIP_BODY才继续往下执行.

8.调用doEndTag方法,这个方法可以返回EVAL_PAGE或者SKIP_PAGE,当返回EVAL_PAGE时,容器将在标签结束时继续计算JSP页面其他的部分;如果返回SKIP_PAGE,容器将在标签结束时停止计算JSP页面其他的部分.

9.调用release()方法释放标签程序占用的任何资源。

public class LoopTag extends BodyTagSupport{
      private int times;

      public int doStartTag() throwsJspException{
             times = 5;
             return super.doStartTag();
      }

      public int doAfterBody() throwsJspException{
             if(times-- >0){ 只要times大于零继续循环,同时times自减
                    try{
                    this.getPreviousOut().println(this.getBodyContent().getString());
                    }catch(Exception e){  }
                    return EVAL_BODY_AGAIN;  //继续执行
             }else{
                    return SKIP_BODY;
             }
      }
}

以上定义了一个循环标签

<taglib:loop>loop.</taglib:loop>

会得到如下输出:

loop.

loop. loop.

loop. loop. loop.

loop. loop. loop.loop.

loop. loop. loop.loop. loop.

实际上,doAfterBody方法内的输出是写到bodyContent缓存中的

BodyTagSupport中,里面的标签可以通过getparent()方法获得上层的标签

JSP1.x 自定义标签的更多相关文章

  1. javaWeb 在jsp中 使用自定义标签输出访问者IP

    1.java类,使用简单标签,jsp2.0规范, 继承 SimpleTagSupport public class ViewIpSimpleTag extends SimpleTagSupport { ...

  2. JSP进阶 之 SimpleTagSupport 开发自定义标签

    绝大部分 Java 领域的 MVC 框架,例如 Struts.Spring MVC.JSF 等,主要由两部分组成:控制器组件和视图组件.其中视图组件主要由大量功能丰富的标签库充当.对于大部分开发者而言 ...

  3. 【转】JSP自定义标签

    转载自:http://www.cnblogs.com/edwardlauxh/archive/2010/05/20/1918587.html tld标签的描述文件 标签的描述文件是一个描述整个标签库标 ...

  4. 自定义标签(客户化jsp标签)

    客户化jsp标签技术是在jsp1.1版本中才出现的,他支持用户在jsp文件中自定义标签,这样可以使jsp代码更加简单,这些可重用的标签能够处理复杂的逻辑运算和事物或定义jsp网页的输出内容和格式. 创 ...

  5. Java Web开发技术教程入门-自定义标签

    回顾: 昨天了解了JSP开发的两种模式Model1和Model2模式.Model1采用JSP+JavaBean技术开发Web应用,它比较适合小规模应用的开发,效率较高,易于实现.但由于在Model1中 ...

  6. [JSP]自定义标签库taglib

    自定义标签的步骤 自定义标签的步骤大概有三步: 1.继承javax.servlet.jsp.tagext.*下提供的几个标签类,如Tag.TagSupport.BodyTagSupport.Simpl ...

  7. [Java] JSP笔记 - 自定义标签

    自定义标签的创建步骤: 自定义标签的四大功能: 自定义标签的类结构: 在 1.0 中呢, 可以将 <body-content> 的值设置为 JSP, 2.0中则不允许在自定义标签体中出现j ...

  8. thinkphp自定义标签库

    thinkphp ~ php中 的类, 的成员变量, 本身是没有类型说明的, 那么我怎么知道它的类型呢? 或初始值呢? 通常在类定义中, 如果能给一个初始值的(对于已知简单类型的),最好给一个初始值, ...

  9. 12 自定义标签/JSTL标签库/web国际化/java web之设计模式和案例

    EL应用      自定义一个标签,实现两个字符串的相加 1回顾      1.1servlet生命周期           init(ServletConfig)           service ...

随机推荐

  1. codefroces 297E Mystic Carvings

    problem:一个圆上依次有1~2*n的数字.每个数字都有且只有另一个数字与他相连.选出三条线,使得每条线的两端之间隔的最少点(只包括被选择的6个点)的个数相等.输入输出格式输入格式: The fi ...

  2. 小明搬家_NOI导刊2010提高(05)

    题目描述 小明要搬家了,大家都来帮忙. 小明现在住在第N楼,总共K个人要把X个大箱子搬上N楼. 最开始X个箱子都在1楼,但是经过一段混乱的搬运已经乱掉了.最后大家发现这样混乱地搬运过程效率太低了,于是 ...

  3. hdu 5893 (树链剖分+合并)

    List wants to travel Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/O ...

  4. hdu 5880 AC自动机

    Family View Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  5. 【USACO07NOV】电话线Telephone Wire

    题目描述 电信公司要更换某个城市的网线.新网线架设在原有的 N(2 <= N <= 100,000)根电线杆上, 第 i 根电线杆的高度为 height_i 米(1 <= heigh ...

  6. ●POJ 3348 Cows

    题链: http://poj.org/problem?id=3348 题解: 计算几何,凸包,多边形面积 好吧,就是个裸题,没什么可讲的. 代码: #include<cmath> #inc ...

  7. ●hihocoder #1394 网络流四·最小路径覆盖

    题链: http://hihocoder.com/problemset/problem/1394 题解: 有向图最小路径覆盖:最少的路径条数不重不漏的覆盖所有点. 注意到在任意一个最小路径覆盖的方案下 ...

  8. hihocoder 1075 : 开锁魔法III

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  9. 【集训第二天·翻水的老师】--ac自动机+splay树

    今天是第二天集训.(其实已经是第三天了,只是昨天并没有机会来写总结,现在补上) 上午大家心情都很愉快,因为老师讲了splay树和ac自动机. 但到了下午,我们的教练竟然跑出去耍了(excuse me? ...

  10. python 中range numpy.arange 和 numpy.linspace 的区别

    1.返回值不同 range返回一个range对象,numpy.arange和numpy.linspace返回一个数组. 2.np.arange的步长可以为小数,但range的步长只能是整数. 与Pyt ...