热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

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
则jsp引擎分析到 时调用doStratTag, 分析到时调用doEndTag

2、建立TLD文件

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

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

将该文件复制到Web应用的WEB-INF/路径,或WEB-INF的任意子路径下,并对该文件进行简单修改,修改后的helloworld.tld文件代码如下:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>



  1.0

  myhelloworld

  

  

    

    

      

      helloWorld

      

      org.lxh.taglib.HelloWorldTag

      

      empty

    

问题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标签



  

  field

  

  com.able.tag.FieldTag

  

  empty

  

    field

    true 

    true

  

  

    count

    true

  

3.jsp中定义标签:

七、如何创建标签处理类

1、引入必需的资源

import javax.servlet.jsp.*; import javax.servlet.http.*; import java.util.*; import java.io.*;
2、继承TagSupport类并覆盖doStartTag()/doEndTag()方法

3、从ServletContext对象中获取java.util.Properties对象

4、从Properties对象中获取key对应的属性值

5、对获取的属性进行相应的处理并输出结果

创建标签库描述文件(Tag Library Descriptor)

1、标签库描述文件,简称TLD,采用XML文件格式,定义了用户的标签库。TLD文件中的元素可以分成3类:

A.标签库元素
B.标签元素
C.标签属性元素

2、标签库元素用来设定标签库的相关信息,它的常用属性有:

A.shortname:指定Tag Library默认的前缀名(prefix);

B.uri:设定Tag Library的惟一访问表示符。

3、标签元素用来定义一个标签,它的常见属性有:

A.name:设定Tag的名字;

B.tagclass:设定Tag的处理类;

C.bodycontent:设定标签的主体(body)内容。

1)empty:表示标签中没有body;
2)JSP:表示标签的body中可以加入JSP程序代码;
3)tagdependent:表示标签中的内容由标签自己去处理。

4、标签属性元素用来定义标签的属性,它的常见属性有:

A.name:属性名称;
B.required:属性是否必需的,默认为false;
C.rtexprvalue:属性值是否可以为request-time表达式,也就是类似于<%=…% >的表达式。

八、在Web应用中使用标签

1、如果Web应用中用到了自定义JSP标签,则必须在web.xml文件中加入元素,它用于声明所引用的标签所在的标签库

/sometaglib
/WEB-INF/someTLD.tld

2、设定Tag Library的惟一标示符,在Web应用中将根据它来引用Tag Libray;

3、指定和Tag Library对应的TLD文件的位置;

4、在JSP文件中需要加入

 /WEB-INF/test.tld
 /WEB-INF/test.tld

5.2.在JSP中使用此标签
<%@ taglib uri="/testTag" prefix="mytag"%>


WEB页面输出结果如下:
自定义标签输出流:Hello,夏中伟! Hi,World!

循环标签体类:ForEach.java

 

 1import java.util.Collection;

 2import java.util.Iterator;

 3

 4import javax.servlet.jsp.JspException;

 5import javax.servlet.jsp.tagext.BodyContent;

 6import javax.servlet.jsp.tagext.BodyTagSupport;

 7

 8public class ForEach  extends BodyTagSupport

 9{

10  private String id;

11  private String collection;

12  private Iterator iter;

13  

14  public void setCollection(String collection)

15  {

16    this.collection = collection;

17  }

18  public void setId(String id)

19  {

20    this.id = id;

21  }

22  

23  //遇到开始标签执行

24  public int doStartTag() throws JspException

25  {

26    Collection coll = (Collection) pageContext.findAttribute(collection);

27    // 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。

28    if(coll==null||coll.isEmpty()) return SKIP_BODY;

29    

30    iter = coll.iterator();

31    pageContext.setAttribute(id, iter.next());

32    // 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法

33    // 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示

34    return EVAL_BODY_INCLUDE;

35  }

36  

37  //在doInitBody方法之前执行,在这里被绕过不执行

38  @Override

39  public void setBodyContent(BodyContent arg0)

40  {

41    System.out.println("setBodyContent");

42    super.setBodyContent(arg0);

43  }

44  //此方法被绕过不会被执行

45  @Override

46  public void doInitBody() throws JspException

47  {

48    System.out.println("doInitBody");

49    super.doInitBody();

50  }

51  

52  //遇到标签体执行

53  public int doAfterBody() throws JspException

54  {

55    if(iter.hasNext()) 

56    {

57      pageContext.setAttribute(id, iter.next());

58      return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体

59    }

60    return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。

61  }

62  

63  //遇到结束标签执行

64  public int doEndTag() throws JspException

65  {

66    System.out.println("doEndTag");

67    return EVAL_PAGE;

68  }

69

70}

 

 获取VO属性类:GetProperty.java

 

 1import java.lang.reflect.Method;

 2

 3import javax.servlet.jsp.JspException;

 4import javax.servlet.jsp.tagext.BodyTagSupport;

 5

 6public class GetProperty extends BodyTagSupport

 7{

 8

 9  private String name;

10  private String property;

11

12  public void setName(String name)

13  {

14    this.name = name;

15  }

16

17  public void setProperty(String property)

18  {

19    this.property = property;

20  }

21

22  @SuppressWarnings("unchecked")

23  public int doStartTag() throws JspException

24  {

25    try

26    {

27      Object obj = pageContext.findAttribute(name);

28      

29      if (obj == null) return SKIP_BODY;

30      

31      Class c = obj.getClass();

32      //构造GET方法名字 get+属性名(属性名第一个字母大写)

33      String getMethodName = "get" + property.substring(0, 1).toUpperCase() 

34                              + property.substring(1, property.length());

35      Method getMethod = c.getMethod(getMethodName, new Class[]{});

36      

37      pageContext.getOut().print(getMethod.invoke(obj));

38      System.out.print(property + ":" + getMethod.invoke(obj) + "t");

39    } catch (Exception e)

40    {

41      e.printStackTrace();

42    }

43    return SKIP_BODY;

44  }

45

46  public int doEndTag() throws JspException

47  {

48    return EVAL_PAGE;

49  }

50}

51

52表达式直接访问此类中静态的方法:ELFunction.java

53public class ELFunction 

54{

55 public static int add( int i,int j )

56 {

57  return i+j;

58 }

59}

 

  写一个测试用的VO类:UserVo.java

 

 1public class UserVo

 2{

 3  private String name;

 4  private String password;

 5  

 6  public String getName()

 7  {

 8    return name;

 9  }

10  public void setName(String name)

11  {

12    this.name = name;

13  }

14  public String getPassword()

15  {

16    return password;

17  }

18  public void setPassword(String password)

19  {

20    this.password = password;

21  }

22}

 

  建好TLD文件tag.tld,放在WEB-INF目录下

 

 1<&#63;xml version="1.0" encoding="utf-8"&#63;>

 2

 7

 8 自定义标签

 9 JSTL core

10 1.1

11 firstLabel

12 http://java.sun.com/jsp/jstl/core

13

14 

15 

16  forEach

17  exercise.taglib.ForEach

18  

19  JSP

20  

21   id

22   true

23   true

24  

25  

26   collection

27   true

28   true

29  

30 

31

32 

33 

34  getProperty

35  exercise.taglib.GetProperty

36  empty

37  

38   name

39   true

40   true

41  

42  

43   property

44   true

45   true

46  

47 

48

49 

50    

51     add

52     exercise.taglib.ELFunction

53     int add(int,int)

54    

55

在web.xml文件中配置自定义标签



 

 firstTag

 /WEB-INF/tag.tld

 



 
在jsp文件中使用标签:tag.jsp


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ taglib uri="firstTag" prefix="my"%>





 

 







 

 




<%

 List list = new ArrayList();

 list.add(userVo1);

 list.add(userVo2);

 pageContext.setAttribute("voList",list);

%>





 

 

 

 

 

 

This is my JSP page:测试taglib.


自定义迭代标签:

姓名密码

表达式调用类的静态方法:

2+5=${my:add(2,5)}

以上就是小编为大家带来的jsp中自定义Taglib详解全部内容了,希望大家多多支持~


推荐阅读
  • 下面根据配置文件,来说明一些底层与webservices的关系:回顾一下servlet的映射模式。我们知道,servlet是从javax.servlet.http.HttpServ ... [详细]
  • 解决CSS因MIME类型不匹配导致的加载失败问题
    本文详细介绍了在Web开发过程中,遇到CSS文件因MIME类型不匹配而无法正确加载的问题及其解决方案,适合前端开发者阅读。 ... [详细]
  • 本文档整理了公司内部常用的网站链接和重要资源路径,包括部门周报、内控报销系统、邮件服务等,同时提供了相关数据库的登录信息。 ... [详细]
  • 本文详细解析了Tomcat服务器的核心配置文件server.xml,包括其主要功能、结构组成及各标签的具体作用。 ... [详细]
  • 本文详细介绍了C++中常见的容器(如列表、向量、双端队列等)及其迭代器的实现方式,通过具体代码示例展示了如何使用这些容器和迭代器。 ... [详细]
  • Android 手机安全应用首屏布局设计
    本文详细介绍了如何构建一个功能丰富的手机安全应用的首个导航界面布局。通过实例代码和效果展示,帮助开发者快速理解和实现相关功能。 ... [详细]
  • 解决fetch上传图片至微信公众号H5页面的问题
    在近期的一个项目需求中,需要在微信公众号内嵌入H5页面,并实现用户通过该页面上传图片的功能,包括拍摄新照片或从已有相册中选择。前端开发中采用了fetch API进行接口调用,但遇到了上传图片时数据无法正确传递的问题。 ... [详细]
  • Python作为一种广泛使用的高级编程语言,以其简洁的语法、强大的功能和丰富的库支持著称。本文将详细介绍Python的主要特点及其在现代软件开发中的应用。 ... [详细]
  • 手把手教你构建简易JSON解析器
    本文将带你深入了解JSON解析器的构建过程,通过实践掌握JSON解析的基本原理。适合所有对数据解析感兴趣的开发者。 ... [详细]
  • 本文详细介绍了如何手动编写兼容IE的Ajax函数,以及探讨了跨域请求的实现方法和原理,包括JSONP和服务器端设置HTTP头部等技术。 ... [详细]
  • 本文将详细介绍如何使用ViewPager实现多页面滑动切换,并探讨如何去掉其默认的左右切换动画效果。ViewPager是Android开发中常用的组件之一,用于实现屏幕间的内容切换。 ... [详细]
  • 本文介绍了jQuery的基本使用方法及AJAX技术的基础知识,包括选择器、事件处理、DOM操作、动画效果等核心功能,以及如何利用AJAX实现页面的部分刷新。 ... [详细]
  • 统一幻灯片标题:使用母版功能的技巧
    本文详细介绍了如何通过PowerPoint中的幻灯片母版功能,实现所有幻灯片标题的一致性设置。同时,提供了其他办公软件和编程相关的实用技巧。 ... [详细]
  • 本文详细介绍了如何使用 Tomcat 进行 Web 应用的部署,包括 .war 和 .jar 文件的打包与部署,以及 Tomcat 的基本配置和管理功能,如多虚拟主机配置、基于 Web 的管理和安全设置。 ... [详细]
  • 经过一段时间的学习与实践,我已经使用D3.js完成了一些项目。鉴于中文D3教程稀缺,而英文资料虽丰富却对英语水平有一定要求,特此撰写一系列D3实战文章,旨在通过具体案例(如统计数据可视化、地图信息展示等)分享D3的使用技巧,促进技术交流。 ... [详细]
author-avatar
卡夫卡咯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有