2026世界杯_2004年世界杯 - 1606811.com

首页 > 击剑世界杯 > Java第四十八天,Jsp之Taglib,自定义标签详解

Java第四十八天,Jsp之Taglib,自定义标签详解

理论知识

一、标签的本质是什么

自定义标签实际上是一个实现了特定接口的Java类,它封装了一些常用功能,在运行时被相应的代码所替换;它与 JavaBean 的最大区别就是 JavaBean 没有默认的上下文(JspContext),但是标签有。

自定义标签由标记处理程序和标签描述组成;

标记处理程序:当遇到特定标记时,标记处理程序就会告诉系统应该做什么,类中包含了要执行的 java 代码标签描述:声明了怎么使用这个标签标记:可以带有属性和主体,这些属性和主体是可选的,最简单的标记是既没有属性也没有主体二、标签接口介绍

JSP 所有的标签都实现了 javax.servlet.jsp.tagext.JspTag 接口;该接口的两个直接子接口如下:

SimpleTag ===> JSP2.0 新增加的接口(后文中统一称作简单标签)Tag ===> 它是经典的、必须实现的接口,它有一个直接子接口就是IterationTag(后文中统一称作传统标签)

Tag 接口有一个直接子接口 IterationTag (后文中统一称作传统标签),该接口继承了 Tag 接口;

Tag 接口有一个直接子接口 TagSupport,该接口实现了 Tag 接口;(TagSupport 接口有一个直接子接口 BodyTagSupport ;它允许带有 body 的标签)

三、自定义标签库基本理论知识

1.自定义标签库体系结构

2.自定义标签处理程序组件

3.基本概念

标签(Tag):让JSP页面实现特定功能,通过标签可以使JSP网页变得简洁并且易于维护,是一种XML元素,它的名称和属性都对大小写敏感标签库( Tag library):由一系列功能相似、逻辑上互相联系的标签构成的集合,同一个标签库的“前缀”相同标签库描述文件( Tag Library Descriptor):是一个ⅩML文件,它提供了标签库中类和JSP中标签引用的映射关系,也是一个配置文件,与 web.xm类似标签处理类( Tag Handle Class):是一个Java类,这个类直接或间接的继承了 Tag 接口,也可能实现了Tag或其子接口,通过该类可以自已定义JSP标签的具体功能4.标签的声明周期

当容器创建一个新的标签实例后,通过 setPageContext 来设置标签的页面上下文使用 setParent 方法设置这个标签的上一级标签,如果没有上一级嵌套,设为 null标签的属性,在标签库的描述文件中定义调用 doStartTag 方法,这个方法返回 EVAL_BODY_INCLUDE 和 SKIP_BODY(EVAL_BODY_INCLUDE:计算标签的 Body;SKIP_BODY:不计算标签的 Body)调用 doEndTag 方法,这个方法返回 EVAL_PAGE 或 SKIP_PAGE(EVAL_PAGE:容器将在结束时继续计算 jsp 页面的其他部分;SKIP_PAGE:容器将在标签结束时停止计算 jsp 页面的其他部分)调用 realse()方法释放标签程序占用的任何资源

生命周期中各个函数与关键字的含义:

1.doStartTag()

遇到自定义标签的开始标记时去调用标签处理类的方法,返回值为含义如下

EVAL_ BODY_INCLUDE(表示标签体要执行,执行结果放在当前输出流中)SKP_BODY(不执行标签体)2.doEndTag()

遇到自定义标签的结束标记时去调用标签处理类的方法;返回值及其含义如下:

EVAL_PAGE:JSP页面的剩余内容将继续执行SKIP_PAGE:Jsp页面的剩余内容不执行3.doAfterBody()

是 IterationTag 接口増加的方法,在执行完标签体后调用,如果没有标签体,该方法将不会调用。该方法的返回值及其含义如下:

SKIP_BODY:跳过标签体EVAL_BODY_AGAIN:重复执行标签体4.setBodyContent()

是 BodyTag 接口中设置 bodyContent 属性的方法,以备后面获取标签体内容;只有在 doStartTag() 返回 EVAL_BODY _BUFFERED才执行

5.创建自定义标签的步骤

创建标签处理类编写、部署标签库描述(TLD)文件在 web. xml 文件中配置标签库信息在JSP文件中使用标签库6.标签库描述(TLD)文件

(1)作用

标签库描述(TLD)文件的作用是由标签找到对应的标签处理类

(2)注意事项

标签库描述(TLD)文件的扩展名为tld,是 xml 类型文件,通常放在 META INF 或 WEB-INF 或其子目录中,但不能存放在 WEB\INF\classes 目录和 WEB-INF\Iib目录中

(3)主要标记

url 标记 ===> 为每个自定义标签找到对应的处理类。uri包含了一个字符串,容器用它来定位TLD文件,在TLD文件中可以找到标签库中所有标签处理类的名称,也可以在 web.xml中设置

description 标记 ===> 描述信息

display-name 标记 ===> 被可视化工具用来显示的名称(可选)

tlib-version 标记 ===> 此标签库的版本

shortname 标记 ===> 标签的“前缀”;用来标识标签库,同一标签库的前缀相同

tag 标记 ===> 标签

其中 tag 标记可包含如下子标记

标签名

包名.标签处理类

...:可设置属性名、是否必需、属性值是否为运行时的表达式等

..

标签体可以有4种取值:

empty(无标签体)JSP(默认,标签体可含JSP代码)scriptless(标签体可以包含EL、JSP标准动作,但不能有脚本)tagdependent(标签体交由标签处理)

(4)自定义标签的调用过程

Web容器根据标签前缀,获得 taglib 指令中的 uri 属性值Web容器根据 uri 属性在 web.xml 找到对应的 元素从 元素中获得对应的 元素的值Web容器根据 < taglib-location> 元素的值从 WEB-INF/ 目录下找到对应的td文件从 tld 文件中找到与标签名对应的 元素从 元素中获得对应的 元素的值Web容器根据元素的值创建相应的标签处理类实例Web容器调用这个实例的 doStartTag/doEndTag 方法完成相应的处理技术实战

一、基于 Tag 接口开发自定义标签(无属性、无标签体)

1.创建标签处理类

package taglib;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.JspTagException;

import javax.servlet.jsp.PageContext;

import javax.servlet.jsp.tagext.Tag;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class MyTaglib implements Tag {

private PageContext pageContext;

private Tag parent;

public MyTaglib() {

super();

}

@Override

public void setPageContext(PageContext pageContext) {

this.pageContext = pageContext;

}

@Override

public void setParent(Tag tag) {

this.parent = tag;

}

@Override

public Tag getParent() {

return this.parent;

}

@Override

public int doStartTag() throws JspException {

//返回 SKIP_BODY,表示不计算标签体

return SKIP_BODY;

}

@Override

public int doEndTag() throws JspException {

try {

SimpleDateFormat sdf = new SimpleDateFormat();

sdf.applyPattern("yyyy-MM-dd HH:mm:ss");

Date date = new Date();// 获取当前时间

pageContext.getOut().write(sdf.format(date));

} catch (IOException e) {

throw new JspTagException(e.getMessage());

}

return EVAL_PAGE;

}

@Override

public void release() {

}

}

2.编写、部署标签库描述(TLD)文件

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">

学习如何使用 Tag 接口

1.0

tools

/learnTag

基于 Tag 接口的自定义标签

showTime

taglib.MyTaglib

empty

3.在 web. xml 文件中配置标签库信息

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd" >

Archetype Created Web Application

/learnTag

/WEB-INF/tlds/MyTaglib.tld

4.在JSP文件中使用标签库

<%@ taglib prefix="tools" uri="/learnTag" %>

二、基于 TagSupport 抽象类开发自定义标签(无属性、无标签体)

1.创建标签处理类

注意:继承 TagSupport 抽象类实现自定义标签时,只需要实现 需要用到的方法 即可,即不必实现任何不需要的方法

package tagSupport;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.JspTagException;

import javax.servlet.jsp.tagext.TagSupport;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class MyTaglibSupport extends TagSupport {

@Override

public int doEndTag() throws JspException {

try {

SimpleDateFormat sdf = new SimpleDateFormat();

sdf.applyPattern("yyyy-MM-dd HH:mm:ss");

Date date = new Date();// 获取当前时间

pageContext.getOut().write(sdf.format(date));

} catch (IOException e) {

throw new JspTagException(e.getMessage());

}

return EVAL_PAGE;

}

}

2.编写、部署标签库描述(TLD)文件

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">

学习如何使用 Tag 接口

1.0

tools

/learnTag

基于 Tag 接口的自定义标签

showTime

taglib.MyTaglib

empty

showTimeV2

tagSupport.MyTaglibSupport

empty

3.在 web. xml 文件中配置标签库信息

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd" >

Archetype Created Web Application

/learnTag

/WEB-INF/tlds/MyTaglib.tld

4.在JSP文件中使用标签库

<%@ taglib prefix="tools" uri="/learnTag" %>

三、基于 TagSupport 抽象类开发自定义标签(有属性、无标签体)

1.创建标签处理类

package tagSupport;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.JspTagException;

import javax.servlet.jsp.tagext.TagSupport;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class MyTaglibSupportAttr extends TagSupport {

// 对于有属性的标签,需要在标签处理类中设置同名的属性,并为属性设置 get 和 set 方法

private String country;

private String city;

public String getCountry() {

return country;

}

public void setCountry(String country) {

this.country = country;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

@Override

public int doEndTag() throws JspException {

try {

SimpleDateFormat sdf = new SimpleDateFormat();

sdf.applyPattern("yyyy-MM-dd HH:mm:ss");

Date date = new Date();// 获取当前时间

pageContext.getOut().write(country + "-" + city + ": " + sdf.format(date));

} catch (IOException e) {

throw new JspTagException(e.getMessage());

}

return EVAL_PAGE;

}

}

2.编写、部署标签库描述(TLD)文件

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">

学习如何使用 Tag 接口

1.0

tools

/learnTag

基于 Tag 接口的自定义标签

showTime

taglib.MyTaglib

empty

showTimeV2

tagSupport.MyTaglibSupport

empty

showTimeV3

tagSupport.MyTaglibSupportAttr

empty

country

true

true

city

true

true

3.在 web. xml 文件中配置标签库信息

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd" >

Archetype Created Web Application

/learnTag

/WEB-INF/tlds/MyTaglib.tld

4.在JSP文件中使用标签库

<%@ taglib prefix="tools" uri="/learnTag" %>

四、基于 BodyTagSupport 抽象类开发自定义标签(有属性、有标签体)

1.注意事项

带有 body 的 Tag 必须实现 javax.servlet.jsp.tagext.BodyTag 接口,BodyTag 接口中定义了处理标签的方法;

2.带有标签体的标签的生命周期:

当容器创建一个新的标签实例后,通过 setPageContext 来设置标签页面的上下文使用 setParent 方法设置这个标签的上一级标签,如果没有上一级嵌套,设置为 null设置标签的属性,在标签的描述文件中定义调用 doStartTag 方法,如果返回 EVAL_BODY_INCLUDE,就计算标签的 BODY;如果返回SKIP_BODY,就不计算标签的 Body调用 setBodyContent 设置当前的 BodyContent调用 doInitBody,如果计算 BodyContent 时需要进行初始化,就在这个方法中进行每次计算完 BodyTag 后调用 doAfterBody,如果返回 EVAL_BODY_TAG,表示继续计算一次 bodytag,直到返回 SKIP_BODY 才执行第 8 步调用 doEndTag 方法,如果返回 EVAL_PAGE 时,容器将在标签结束后继续计算 jsp 页面其他部分;如果返回 SKIP_PAGE,容器将在标签结束时停止计算 jsp 页面的其他部分调用 realse()方法释放标签程序占用的任何资源

3.BodyTagSupport 类

① BodyTagSupport 继承自 TagSupport 类,同时实现了 BodyTag 接口

② 该类增加了一个成员变量BodyContent;BodyContent类是JspWriter的子类,主要用于访问标签体,保存标签体处理结果

③ 该类增加了 setBodyContent(BodyContent b)、doInitBody()、doAfterBody() 方法

4.分析修改标签体的步骤

继承BodyTagSupport类或实现BodyTag接口 doStartTag()返回 EVAL_BODY_BUFFERED(表示标签体要执行,执行结果放在当前输出流中)在doAfterBody()方法中处理标签体(调用getBodyContent()、 BodyContent的有关方法,获取标签体内容,并将程序处理结果存放到输出流由上可知,要得到标签体内容并进行修改,需要用到一个重要类— BodyContent,它有两个重要方法

String getString():以字符串方式返回标签体内容

public JspWriter getEnclosingWriter():得到封装的JspWriter对象

1.创建标签处理类

package tagSupport;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.JspTagException;

import javax.servlet.jsp.JspWriter;

import javax.servlet.jsp.tagext.BodyTagSupport;

import javax.servlet.jsp.tagext.TagSupport;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class MyTaglibSupportAttrBody extends BodyTagSupport {

// 对于有属性的标签,需要在标签处理类中设置同名的属性,并为属性设置 get 和 set 方法

private String country;

private String city;

public String getCountry() {

return country;

}

public void setCountry(String country) {

this.country = country;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

@Override

public int doStartTag() throws JspException {

return EVAL_BODY_BUFFERED;

}

@Override

public int doEndTag() throws JspException {

return EVAL_PAGE;

}

@Override

public void doInitBody() throws JspException {

super.doInitBody();

}

@Override

public int doAfterBody() throws JspException {

JspWriter out = bodyContent.getEnclosingWriter();

try {

out.println(bodyContent.getString() + country + "-" +city + "
");

} catch (IOException e) {

e.printStackTrace();

}

bodyContent.clearBody();

return super.doAfterBody();

}

}

2.编写、部署标签库描述(TLD)文件

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">

学习如何使用 Tag 接口

1.0

tools

/learnTag

基于 Tag 接口的自定义标签

showTime

taglib.MyTaglib

empty

showTimeV2

tagSupport.MyTaglibSupport

empty

showTimeV3

tagSupport.MyTaglibSupportAttr

empty

country

true

true

city

true

true

showTimeV4

tagSupport.MyTaglibSupportAttrBody

JSP

country

true

true

city

true

true

3.在 web. xml 文件中配置标签库信息

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd" >

Archetype Created Web Application

/learnTag

/WEB-INF/tlds/MyTaglib.tld

4.在JSP文件中使用标签库

<%@ taglib prefix="tools" uri="/learnTag" %>

My home is in :

五、基于 SimpleTag 接口开发自定义标签(有属性、无标签体)

SimpleTag 是JSP2.0 规范新增的一种类型标签,简化了传统标签开发中的复杂操作;

JSP 2.0 中加入了新的创建自制标记的 API,javax.servlet.jsp.tagext.SimpleTag 定义了用来实现简单标记的接口。和JSP 1.2中的已有接口不同的是,SimpleTag接口不使用 doStartTag()和 doEndTag()方法,而提供了一个简单的 doTag()方法。这个方法在调用该标记时只被使用一次。而需要在一个自制标记中实现的所有逻辑过程、循环和对标记体的评估等都在这个方法中实现。

从这个方面来讲,SimpleTag 和 IterationTag 可以达到同等的作用。但 SimpleTag的方法和处理周期要简单得多。在 SimpleTag 中还有用来设置 JSP 内容的 seJspBody()和getJspBody()方法。Web 容器会使用 setJspBody()方法定义一个代表 JSP 内容的 JspFragment 对 象 。 实 现 SimpleTag 标 记 的 程 序 可 以 在 doTag 方 法 中 根 据 需 要 多 次 调 用getJspBody().invoke()方法以处理 JSP 内容

返回类型方法名方法描述voiddoTag()执行业务处理的方法,所有逻辑处理都在这里进行static JspTagfindAncestorWithClass(JspTag from, Class klass)找到最接近给定实例的给定类类型的实例protected JspFragmentgetJspBody()返回容器通过 setJspBody 传入的 bodyprotected JspContextgetJspContext()返回容器通过 setJspContext 传入的页面上下文JspTaggetParent()出于协作目的,返回此标记的父级voidsetJspBody(JspFragment jspBody)存储提供的 JspFragmentvoidsetJspContext(JspContext pc)将提供的 JSP 上下文存储在私有 jspContext 字段中voidsetParent(JspTag parent)设置此标签的父级,用于协作

SimpleTagSupport 生命周期

每次遇到标签时,容器构造一个 SimpleTag 的实例,并且这个构造方法没有参数。和传统标签一样,SimpleTag 不能进行缓冲,故不能重用,每次都要构造新的实例调用构造方法之后,就调用 setJspContext()和 setParent()方法,只有这个标签在另一个标签之内时,才调用 setParent 方法容器调用每个属性的 setter 方法以设置这些属性的值如果存在 body,那么就使用 setJspBody 方法来设置这个标签的标签体。容器调用 doTag 方法,所有的标签逻辑、迭代和 Body 计算,都在这个方法中当 doTag 方法返回时,所有的参数被锁定

1.创建标签处理类

package simpleTablib;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.tagext.SimpleTagSupport;

import java.io.IOException;

public class MySimpleTaglib extends SimpleTagSupport {

private String userName;

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

@Override

public void doTag() throws JspException, IOException {

getJspContext().getOut().println("Your name is " + userName);

}

}

2.编写、部署标签库描述(TLD)文件

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">

学习如何使用 Tag 接口

1.0

tools

/learnTag

基于 Tag 接口的自定义标签

showTime

taglib.MyTaglib

empty

showTimeV2

tagSupport.MyTaglibSupport

empty

showTimeV3

tagSupport.MyTaglibSupportAttr

empty

country

true

true

city

true

true

showTimeV4

tagSupport.MyTaglibSupportAttrBody

JSP

country

true

true

city

true

true

showName

simpleTablib.MySimpleTaglib

empty

userName

true

true

3.在 web. xml 文件中配置标签库信息

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd" >

Archetype Created Web Application

/learnTag

/WEB-INF/tlds/MyTaglib.tld

4.在JSP文件中使用标签库

<%@ taglib prefix="tools" uri="/learnTag" %>




落户原籍地址怎么填写?落户地址是什么
腾讯 WeGame 游戏之夜定档 6 月 16 日,多款新游将曝光消息