jsp中自定义Taglib详解

jsp中自定义Taglib详解

一、自定义标签入门之无参数自定义标签

1.开发自定义标签类

当我们在JSP页面使用一个简单的标签时,底层实际上由标签处理类提供支持,从而可以使用简单的标签来封装复杂的功能,从而使团队更好地协作开发(能让美工人员更好地参与JSP页面的开发)。

自定义标签类都必须继承一个父类:javax.servlet.jsp.tagext.SimpleTagSupport,或者TagSupport除此之外,JSP自定义标签类还有如下要求。

如果标签类包含属性,每个属性都有对应的getter和setter方法。

重写doTag()或者doStartTag()或doEndTag()方法方法,这个方法负责生成页面内容。

首先介绍是不带属性的标签以HelloWorld为例:

Java代码如下:

public class HelloWorldTag extends TagSupport {

 

  private static final long serialVersionUID = -3382691015235241708L;

  @Override

  public int doEndTag() throws JspException {

    try {

      pageContext.getOut().write("Hello World !");

      return super.doEndTag();

    } catch (JspException e) {

      e.printStackTrace();

      return 0;

    } catch (IOException e) {

      e.printStackTrace();

      return 0;

    }

  }

 

  @Override

  public int doStartTag() {

    try {

      pageContext.getOut().write("Hello World");

      return super.doStartTag();

    } catch (JspException e) {

      e.printStackTrace();

      return 0;

    } catch (IOException e) {

      e.printStackTrace();

      return 0;

    }

  }

}

注意:

问题1:tagsupport中的dostartTag和doEndTag这两个方法有什么区别
doStartTag是在扫描到起始标签时调用,doEndTag是在扫描到结束标签是调用。
例如:<helloWorld> helloWorld</helloWorld>
则jsp引擎分析到<helloWorld> 时调用doStratTag, 分析到</helloWorld>时调用doEndTag

2、建立TLD文件

TLD是Tag Library Definition的缩写,即标签库定义,文件的后缀是tld,每个TLD文件对应一个标签库,一个标签库中可包含多个标签,TLD文件也称为标签库定义文件。

标签库定义文件的根元素是taglib,它可以包含多个tag子元素,每个tag子元素都定义一个标签。通常我们可以到Web容器下复制一个标签库定义文件,并在此基础上进行修改即可。例如Tomcat6.0,在webappsexamplesWEB-INFjsp2路径下包含了一个jsp2-example-taglib.tld文件,这就是示范用的标签库定义文件。

将该文件复制到Web应用的WEB-INF/路径,或WEB-INF的任意子路径下,并对该文件进行简单修改,修改后的helloworld.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 web-jsptaglibrary_2_0.xsd"

  version="2.0">

  <tlib-version>1.0</tlib-version>

  <short-name>myhelloworld</short-name>

  <!-- 定义该标签库的URI 必须添加但可以空-->

  <uri></uri>

    <!-- 定义第一个标签 -->

    <tag>

      <!-- 定义标签名 -->

      <name>helloWorld</name>

      <!-- 定义标签处理类 -->

      <tag-class>org.lxh.taglib.HelloWorldTag</tag-class>

      <!-- 定义标签体为空 -->

      <body-content>empty</body-content>

    </tag>

</taglib>

问题1: 为什么要用TagSupport与BodyTagSupport的区别主要是标签处理类是否需要与标签体交互,如果不需要交互的就用TagSupport,否则就用BodyTagSupport。

交互就是标签处理类是否要读取标签体的内容和改变标签体返回的内容。用TagSupport实现的标签,都可以用BodyTagSupport来实现,因为BodyTagSupport继承了TagSupport而不去实现IterationTag接口的,因为BodyTagSupport继承了TagSupport类,并且该类已经实现了IterationTag接口并且实现了功能.

doStartTag()方法在标签开始时执行,要记住每次都要对类进行初始化,避免上一次的遗留数据对操作造成影响。然后判断是否有数据需要处理,如果有,则返回EVAL_BODY_INCLUDE开始处理标签里的内容,如果没有,返回 EVAL_PAGE跳过标签内容执行标签下面的内容。

doAfterBody()方法在每次处理完标签内部内容后执行,判断循环是否已经结束,如果可以继续循环,返回EVAL_BODY_AGAIN用循环得到新的数据再次处理标签内部内容,如果循环结束就返回EVAL_PAGE结束标签。

二、自定义JSP标签的处理过程:

1.在JSP中引入标签库:  
2.在JSP中使用标签库标签
3.Web容器根据第二个步骤中的prefix,获得第一个步骤中声明的taglib的uri属性值
4.Web容器根据uri属性在web.xml找到对应的元素
5.从元素中获得对应的元素的值
6.Web容器根据元素的值从WEB-INF/目录下找到对应的.tld文件
7.从.tld文件中找到与tagname对应的元素
8.凑元素中获得对应的元素的值
9.Web容器根据元素的值创建相应的tag handle class的实例
10. Web容器调用这个实例的doStartTag/doEndTag方法完成相应的处理

三、创建和使用一个Tag Library的基本步骤:

1.创建标签的处理类(Tag Handler Class)
2.创建标签库描述文件(Tag Library Descrptor File)
3.在web.xml文件中配置元素
4.在JSP文件中引人标签库

四、TagSupport类简介:

1.处理标签的类必须扩展javax.servlet.jsp.TagSupport.

2.TagSupport类的主要属性:

A.parent属性:代表嵌套了当前标签的上层标签的处理类

B.pageContex属性:代表Web应用中的javax.servlet.jsp.PageContext对象

3.JSP容器在调用doStartTag或者doEndTag方法前,会先调用setPageContext和setParent方法,设置pageContext和parent。因此在标签处理类中可以直接访问pageContext变量

4.在TagSupport的构造方法中不能访问pageContext成员变量,因为此时JSP容器还没有调用setPageContext方法对pageContext进行初始化

五、TagSupport处理标签的方法:

1.TagSupport类提供了两个处理标签的方法:

public int doStartTag() throws JspException
public int doEndTag() throws JspException

2.doStartTag:但JSP容器遇到自定义标签的起始标志,就会调用doStartTag()方法,doStartTag()方法返回一个整数值,用来决定程序的后续流程。

A.Tag.SKIP_BODY:表示跳过了开始和结束标签之间的代码
B.Tag.EVAL_BODY_INCLUDE:表示标签之间的内容被正常执行
C.Tag.EVAL_BODY_BUFFERED :对包含的内容进行解析

3.doEndTag:但JSP容器遇到自定义标签的结束标志,就会调用doEndTag()方法。doEndTag()方法也返回一个整数值,用来决定程序后续流程。

A.Tag.SKIP_PAGE:表示立刻停止执行网页,网页上未处理的静态内容和JSP程序均被忽略任何已有的输出内容立刻返回到客户的浏览器上。
B.Tag.EVAL_PAGE:表示按照正常的流程继续执行JSP网页

4.doAfterTag:遇到标签体执行

A.Tag.EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体,对标签体循环处理,(存在于javax.servlet.jsp.tagext.IterationTag接口中)
B.Tag.SKIP_BODY

六、创建含有字段的标签:

1.创建标签处理器类FieldTag

package com.able.tag;

 

import java.io.IOException;

 

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.JspWriter;

import javax.servlet.jsp.tagext.TagSupport;

 

public class FieldTag extends TagSupport {

 

  private static final long serialVersionUID = 1540529069962423355L;

   

  private String field;

   

  private Integer count;

 

  @Override

  public int doEndTag() throws JspException {

    try {

      JspWriter out = pageContext.getOut();

      out.print(field);

      out.print(count);

    } catch (IOException e) {

      e.printStackTrace();

    }

    return super.doEndTag();

  }

 

 

 

  public String getField() {

    return field;

  }

 

  public void setField(String field) {

    this.field = field;

  }

 

  public Integer getCount() {

    return count;

  }

 

  public void setCount(Integer count) {

    this.count = count;

  }

  
}

2.在tag.tld文件中天剑tag标签

<tag>

  <!-- 定义标签名 -->

  <name>field</name>

  <!-- 定义标签处理类 -->

  <tag-class>com.able.tag.FieldTag</tag-class>

  <!-- 定义标签体为空 -->

  <body-content>empty</body-content>

  <attribute>

    <name>field</name>

    <required>true</required> <!-- 是否必
上一篇:jsp登录页面的简单实例 雏形
下一篇:jsp登录会话的简单实现