自定义标签主要用于移除Jsp页面中的java代码

快速入门:使用自定义标签输出客户机的IP

移除jsp页面中的java代码,只需要完成两个步骤:

编写一个实现Tag接口的Java类,并覆盖doStartTag方法,把jsp页面中的java代码写到doStartTag方法中。

编写标签库描述符(tld)文件,在tld文件中对自定义标签进行描述。

完成以上操作,即可在JSP页面中导入和使用自定义标签。

查看tag接口api文档,分析自定义标签的执行流程。

自定义标签的创建步骤:

(1)      标签处理器——java类,实现Tag接口

(2)      编写.tld:

JSP页面中使用自定义标签

<dhw:aaa>

<dhw:viewIP>系统自动调用doStartTag()

</dhw:viewIP>系统自动调用doEndTag()

</dhw:aaa>

Tag接口的执行流程

JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法。

1、public voidsetPageContext(PageContext pc), JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。

2、public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。

3、public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。

4、public int doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。

5、public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。

自定义标签功能扩展

自定义标签除了可以移除Jsp页面中的java代码外,它还可以用于完成一些页面逻辑,例如:

通过自定义标签可以控制jsp页面某一部分内容是否执行。

例如:<c:if>标签

通过自定义标签可以控制标签后的jsp页面是否执行。

通过自定义标签可以控制jsp页面某一部分内容重复执行。

例如:<c:foreach>标签

通过自定义标签可以修改jsp页面内容输出。

tld文件中的四种标签体类型

EMPTY  JSP scriptless  tagdepentend

简单标签

由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:

setJspContext方法

setParent和getParent方法

setJspBody方法

doTag方法

SimpleTag方法介绍

setJspContext方法

用于把JSP页面的pageContext对象传递给标签处理器对象

setParent方法

用于把父标签处理器对象传递给当前标签处理器对象

getParent方法

用于获得当前标签的父标签处理器对象

setJspBody方法

用于把代表标签体的JspFragment对象传递给标签处理器对象

doTag方法

用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

SimpleTag接口方法的执行顺序

当web容器开始执行标签时,会调用如下方法完成标签的初始化

WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。

WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。

如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。

如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。

执行标签时:

容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

JspFragment类

javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素。

WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:

getJspContext方法

用于返回代表调用页面的JspContext对象.

public abstractvoid invoke(java.io.Writer out)

用于执行JspFragment对象所代表的JSP代码片段

参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)

invoke方法详解

JspFragment.invoke方法可以说是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:

在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;

在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;

若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。


自定义标签制作步骤:

1.扩展TagSupport

2.标签所对应的tld文件配置

3.在JSP页面引用tld配置文件并使用标签

标签制作常用方法说明:

doStartTag()和doEndTag()返回值处理:

SKIP_BODY (0) :跳过了开始和结束标签之间的代码。
EVAL_BODY_INCLUDE(1):将body的内容输出到存在的输出流中
SKIP_PAGE(5): 忽略剩下的页面。
EVAL_PAGE隐含(6):继续执行下面的页

Test.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'Test.jsp' starting page</title>
  </head>
 
  <body>
    This is my JSP page. <br>
    Date : <%= new java.util.Date().toString() %> <br>
    File : <input value="<%= request.getServletPath() %>" /> 
  </body>
</html>

为了将这个这个Test.jsp改成自定义标签方法,我们分别使用简单标签和内容标签两种不同的方式实现。

1. 简单标签

由于我们需要输出两个内容(日期和文件名),因此我们为标签创建一个参数。具体代码:

DemoTag.java

package com.mycompany;

import java.util.Date;

import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class DemoTag extends TagSupport {
  
  public int doStartTag() throws JspException {    
    try {
      HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
      JspWriter out = pageContext.getOut();      
      
      if (parameter.compareToIgnoreCase("filename") == 0)
        out.print(request.getServletPath());
      else 
        out.print(new Date());
      
    } catch (java.io.IOException e) {
      throw new JspTagException(e.getMessage());
    }
    
    return SKIP_BODY;
  }
  
  private String parameter = "date";
  
  public void setParameter(String parameter) {
    this.parameter = parameter;
  } 
  
  public String getParameter() {
    return parameter;
  }
}

接下来,我们创建标签文件 MyTagLib.tld。标签文件其实只是一个XML格式的说明文件,内容也很简单。

MyTagLib.tld

<?xml version="1.0" encoding="ISO-8859-1"?>
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>

<tag>
  <name>demo</name>
  <tag-class>com.mycompany.DemoTag</tag-class>
  <body-content>empty</body-content>
  <attribute>
    <name>parameter</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>

</taglib>

在这个标签文件中,我们将我们创建的标签取名 demo,并声明了类型和参数(parameter)。将该文件保存在 /WEB-INF 下面。
当然,我们还需要将我们自定义的标签添加到 web.xml 中,否则还是无法使用。

web.xml

<?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" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<jsp-config>
    <taglib>
      <taglib-uri>/WEB-INF/MyTagLib</taglib-uri>
      <taglib-location>/WEB-INF/MyTagLib.tld</taglib-location>
    </taglib>
  </jsp-config>

</web-app>

你可能在别处看到过类似的声明,只是没有外面的 jsp-config,但是我们使用的是DTD 2.4,如果不加,Eclipse 会提示出错。

到此为止,我们的自定义标签算是创建完毕。接下来,我们可以开始改写那个JSP文件来分离代码了。

Test.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@taglib uri="/WEB-INF/MyTagLib" prefix="mytag"%>
<html>
  <head>
    <title>My JSP 'Test.jsp' starting page</title>
  </head>
 
  <body>
    This is my JSP page. <br>
    Date : <mytag:demo parameter="date" /><br>
    File : <mytag:demo parameter="filename" />
  </body>
</html>

上面这些想必你已经很熟悉,我就不做多说了。

2. 内容标签

创建过程和上面大抵相同,只是程序文件和配置内容有些差异。

DemoTag2.java

package com.mycompany;

import java.io.IOException;
import java.util.Date;

import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class DemoTag2 extends BodyTagSupport {
  
  public int doStartTag() throws JspTagException {    
    return EVAL_BODY_BUFFERED;
  }
  
  public int doEndTag() throws JspTagException {
    String body = this.getBodyContent().getString();
    HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
    
    body = body.replace("$date", new Date().toString());
    body = body.replace("$filename", request.getServletPath());
    
    try {
      pageContext.getOut().print(body);
    }
    catch (IOException e) {
      throw new JspTagException(e.getMessage());
    }
    
    return SKIP_BODY;
  }
}

我们将新的标签 DemoTag2 加入到上面的标签文件中。

MyTagLib.tld

<?xml version="1.0" encoding="ISO-8859-1"?>
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>

<tag>
  <name>demo</name>
  <tag-class>com.mycompany.DemoTag</tag-class>
  <body-content>empty</body-content>
  <attribute>
    <name>parameter</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>

<tag>
  <name>demo2</name>
  <tag-class>com.mycompany.DemoTag2</tag-class>
  <body-content>jsp</body-content>
</tag>

</taglib>

web.xml 文件无需修改。

看看同时使用两种标签的Test.jsp效果。

Test.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@taglib uri="/WEB-INF/MyTagLib" prefix="mytag"%>
<html>
  <head>
    <title>My JSP 'Test.jsp' starting page</title>
  </head>
 
  <body>
    This is my JSP page. <br>
    Date : <mytag:demo parameter="date" /><br>
    File : <mytag:demo parameter="filename" />

<hr>

<mytag:demo2>
    Date: $date<br>
    File: $filename
    </mytag:demo2>
  </body>
</html>

JAVA自定义标签教程及实例代码相关推荐

  1. java 自定义标签_Java自定义标签用法实例分析

    本文实例讲述了Java自定义标签用法.分享给大家供大家参考,具体如下: 简单例子 实现一个标签分为两步:(1)继承SimpleTagSupport或TagSupport实现一个控制器(2)创建一个描述 ...

  2. java程序设计颜志军_JSP 自定义标签之一 简单实例

    在JSP中使用自定义标签可以达到这样的目的,事实上,我们所熟知的各类框架基本上都是通过自定义标签的形式来实现的. 通过使用自定义标签,我们可以将实现复杂的逻辑在页面用简单的标签来加以展示.下面我们来实 ...

  3. java自定义标签库的开发

    java自定义标签库的开发 第14章 自定义标签库的开发 14.1 自定义标签介绍 14.2 HelloWorld标签的开发 14.3 开发带Body的标签库 14.4 多个标签的嵌套 14.5 开发 ...

  4. android 自定义本地验证码demo,Android 自定义验证码输入框的实例代码(支持粘贴连续性)...

    需求 1.能自定义输入框个数和样式 2.支持长按粘贴或剪切板内容自动填充(粘贴连续性) 其中第2点是最为重要的,正是其他人没有这点,逼得自己弄一个 示例 别人的示例: 粘贴居然不支持连续性,只能粘贴第 ...

  5. php创建菜单_php实现微信公众号创建自定义菜单功能的实例代码

    目的 创建自定义菜单,实现菜单事件. 首先获取Access_Token 接口: 我用的是测试号,修改APPID和APPSECRET,然后浏览器访问上面这个Url即可生成Access_Token 然后配 ...

  6. 大疆 DJI mobile SDK系列详细教程——运行实例代码(跑通大疆官方提供Mobile SDK里的sample code)

    大疆 DJI mobile SDK系列详细教程--运行实例代码(跑通大疆官方提供Mobile SDK里的sample code) 文章目录 一.官方文献与资源地址 二.操作步骤 提示:昨天在尝试跑通大 ...

  7. java 大学简明教程_Simply-Java 《JAVA大学简明教程:实例程序设计》例子及习题源代码 - 下载 - 搜珍网...

    JAVA大学简明教程:实例程序设计/附书源代码/Tutorial01/MovingShapes/BoundedShape.class JAVA大学简明教程:实例程序设计/附书源代码/Tutorial0 ...

  8. java自定义标签简单_JSP 自定义标签之一 简单实例

    在jsp中使用自定义标签可以达到这样的目的,事实上,我们所熟知的各类框架基本上都是通过自定义标签的形式来实现的. 通过使用自定义标签,我们可以将实现复杂的逻辑在页面用简单的标签来加以展示.下面我们来实 ...

  9. java 自定义标签实现的_Java实现自定义标签的步骤——带你实现自己的标签

    一.自定义标签: 使用标签的好处:使用方便.简洁.实现代码重用 二.自定义标签的形式: 1.标签属性: 2.标签体 (1)无标签体――空标签 (2)有标签体 · 普通文本 · 脚本片断 · 脚本表达式 ...

最新文章

  1. 巧用Excel 2010数据透视表制作销售报表
  2. 考前自学系列·计算机组成原理
  3. iOS 导航栏实现总结
  4. 中的listeners_Netty源码学习(6)-- Netty中的异步处理
  5. uploadify 配置后,页面显示无效果
  6. 8.MySQL 数据操作 DML
  7. Ubuntu下设置环境变量的三种方法
  8. pause容器作用_容器编排之战(四)连载
  9. java easyui条件组合查询_EasyUi+Spring Data 实现按条件分页查询
  10. 三维点云学习(5)3-Deep learning for Point Cloud-PointNet++
  11. Code Review中的几个提示
  12. 微pe不识别nvme固态硬盘_WinPE无法识别NVMe SSD硬盘,如何重装系统
  13. MapReduce作业运行机制
  14. python 坐标轴 单位刻度_Python绘图总结(Matplotlib篇)之坐标轴及刻度
  15. java毕业设计疫情返乡人员管理系统Mybatis+系统+数据库+调试部署
  16. Java设计模式系列3-----装饰模式,策略模式,观察者模式
  17. Linux下修改Oracle字符集为ZHS16GBK
  18. TOP20精选议题引领 | K+峰会深圳站圆满收官!
  19. 《图解数据结构》(第二版)读书笔记
  20. Paper/CV之IA:《First Order Motion Model for Image Animation图像动画的一阶运动模型》翻译与解读

热门文章

  1. MP4转MP3无需各种会员的超级免费解决方案
  2. 什么是高绩效团队_建立高绩效团队的方式1
  3. 携手共赢 决胜2021——芯讯通全球合作伙伴大会
  4. docker运行cabot
  5. Android popu菜单
  6. Flex圣杯布局(简易)
  7. 广东省中山市第七届小学生信息学邀请赛题解 螺旋方阵
  8. 知其然也要知其所以然---Kernel上报电量UEvent事件流程分析
  9. python 语音朗读软件-python 利用pyttsx3文字转语音过程详解
  10. 系统资源不足,无法完成请求服务。