0%
这是一片思考的空间 -- arthinking
Spring 重构&代码整洁之道 软件设计 JVM 并发编程 数据结构与算法 分布式 存储 网络 微服务 设计模式
Java技术栈 - 涉及Java技术体系

Java Web笔记 - 客户化JSP标签库 自定义标签

1、客户化JSP标签库:

客户化JSP标签技术是在JSP1.1版本中出现的,支持用户在JSP文件中自定义标签,从而使JSP代码更加简洁。

这些可重用的标签能处理复杂的逻辑运算和事务,或者定义JSP网页的输出内容和格式。

2、实现自定义标签的相关API:

Servlet容器编译JSP网页时,如果遇到自定义标签,就会调用这个标签的处理类。

标签处理类必须扩展以下两个类之一:

javax.servlet.jsp.tagext.TagSupport javax.servlet.jsp.tagext.BodyTagSupport

public class TagSupport
extends Object
implements IterationTag, Serializable

A base class for defining new tag handlers implementing Tag.

几个重要的方法:

setValue
public void setValue(String k,
Object o)

Associate a value with a String key.

Parameters:
k - The key String.
o - The value to associate.

在标签处理类中设置key/value

getValue
public Object getValue(String k)

Get a the value associated with a key.

Parameters:
k - The string key.

Returns:
The value associated with the key, or null.

在标签处理类中根据参数key返回匹配的value

removeValue
public void removeValue(String k)

Remove a value associated with a key.

Parameters:
k - The string key.

在标签处理类中删除key/value

setPageContext
public void setPageContext(PageContext pageContext)

Set the page context.

Specified by:
setPageContext in interface Tag

Parameters:
pageContext - The PageContext.

See Also:
Tag.setPageContext(javax.servlet.jsp.PageContext)

设置PageContext对象,该方法由Servlet容器在调用doStartTag或doEndTag方法前调用

setParent
public void setParent(Tag t)

Set the nesting tag of this tag.

Specified by:
setParent in interface Tag

Parameters:
t - The parent Tag.

See Also:
Tag.setParent(Tag)

设置嵌套了当前标签的上层标签的处理类,该方法由Servlet容器在调用doStartTag或doEndTag方法前调用

getParent
public Tag getParent()

The Tag instance most closely enclosing this tag instance.

Specified by:
getParent in interface Tag

Returns:
the parent tag instance or null

See Also:
Tag.getParent()

返回嵌套了当前标签的上层标签的处理类

doStartTag
public int doStartTag()
throws JspException

Default processing of the start tag, returning SKIP_BODY.

Specified by:
doStartTag in interface Tag

Returns:
SKIP_BODY

Throws:
JspException - if an error occurs while processing this tag

See Also:
Tag.doStartTag()

当Servlet容器遇到自定义标签的起始标志,就会调用doStartTag方法。

doStartTag方法返回一个整数值,用来决定程序的后续流程,有两个可选值:

Tag.SKIP_BODY:表示忽略标签之间的内容 Tag.EVAL_BODY_INCLUDE:表示标签之间的内容会正常执行

doEndTag
public int doEndTag()
throws JspException

Default processing of the end tag returning EVAL_PAGE.

Specified by:
doEndTag in interface Tag

Returns:
EVAL_PAGE

Throws:
JspException - if an error occurs while processing this tag

See Also:
Tag.doEndTag()

当Servlet容器遇到自定义标签的结束标志,就会调用doEndTag方法。

doEndTag返回一个整数值,用来决定程序后续流程,有两个可选值:

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

两个重要的属性:

pageContext
protected PageContext pageContext
The PageContext.

代表Web应用中的javax.servlet.jsp.PageContext对象

PageContext对象提供了访问ServletContext,Request和Session的方法。

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

JSP容器在调用doStartTag或doEndTag方法前,先调用setPageContext和setParent方法,设置pageContext和parent。

在doStartTag或doEndTag方法中可以通过getParent方法获取上层标签的处理类。在TagSupport类中定义了protected类型的pageContext成员变量,因此在标签处理类中可以直接访问pageContext变量。

PageContext的两个访问Web应用的共享数据的方法:

public void setAttribute(String name, Object value, int scope)
public void getAttribute(String name , int scope)

public class BodyTagSupport
extends TagSupport
implements BodyTag
A base class for defining tag handlers implementing BodyTag.

3、自定义标签属性:

在标签处理类中应该将这个属性作为成员变量,并提供setter和getter方法。

4、创建客户化JSP标签的步骤:

创建标签的处理类

public class MyTag extends TagSupport {

@Override
public int doStartTag() throws JspException {
    try {
        this.pageContext.getOut().println("这是标签的起始处理输出结果");
    } catch (IOException e) {
        e.printStackTrace();
    }
    return this.EVAL_BODY_INCLUDE;
}

@Override
public int doEndTag() throws JspException {
    try {
        this.pageContext.getOut().println("这是标签的结束处理输出结果");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return this.EVAL_PAGE;
}

}

创建标签库描述文件

标签库描述文件后缀名是:.tld

必须保存在WEB-INF目录下。

1.0 1.1 myTag /myTag
<tag>
    <name>myTag</name>
    <tag-class>com.itzhai.tag.MyTag</tag-class>
    <body-content>empty</body-content>
</tag>    

在JSP文件中引入标签库

<%@ taglib uri="/myTag" prefix="pre" %>

使用标签

pre:myTag/

5、创建一个带有属性的自定义标签:

创建标签的处理类

public class MyTag2 extends TagSupport {

private String name;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
@Override
public int doEndTag() throws JspException {

    try {
        this.pageContext.getOut().println(name);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return this.EVAL_PAGE;
}

}

创建标签库描述文件

1.0 1.1 myTag /myTag
<tag>
    <name>myTag</name>
    <tag-class>com.itzhai.tag.MyTag</tag-class>
    <body-content>empty</body-content>
</tag>

<tag>
    <name>myTag2</name>
    <tag-class>com.itzhai.tag.MyTag2</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <name>name</name>
        <required>true</required>
    </attribute>
</tag>

使用自定义标签:

<%@ taglib uri="/myTag" prefix="pre" %>
<pre:myTag2 name="user1"/>

欢迎关注我的其它发布渠道

订阅IT宅
内功修炼
Java技术栈
Java架构杂谈是IT宅精品文章公众号,欢迎订阅:
📄 网络基础知识:两万字长文50+张趣图带你领悟网络编程的内功心法 📄 HTTP发展史:三万长文50+趣图带你领悟web编程的内功心法 📄 HTTP/1.1:可扩展,可靠性,请求应答,无状态,明文传输 📄 HTTP/1.1报文详解:Method,URI,URL,消息头,消息体,状态行 📄 HTTP常用请求头大揭秘 📄 HTTPS:网络安全攻坚战 📄 HTTP/2:网络安全传输的快车道 📄 HTTP/3:让传输效率再一次起飞 📄 高性能网络编程:图解Socket核心内幕以及五大IO模型 📄 高性能网络编程:三分钟短文快速了解信号驱动式IO 📄 高性能网络编程:彻底弄懂IO复用 - IO处理杀手锏,带您深入了解select,poll,epoll 📄 高性能网络编程:异步IO:新时代的IO处理利器 📄 高性能网络编程:网络编程范式 - 高性能服务器就这么回事 📄 高性能网络编程:性能追击 - 万字长文30+图揭秘8大主流服务器程序线程模型
📄 Java内存模型:如果有人给你撕逼Java内存模型,就把这些问题甩给他 📄 一文带你彻底理解同步和锁的本质(干货) 📄 AQS与并发包中锁的通用实现 📄 ReentrantLock介绍与使用 📄 ReentrantReadWriteLock介绍与使用 📄 ReentrantLock的Condition原理解析 📄 如何优雅的中断线程 📄 如何优雅的挂起线程 📄 图解几个好玩的并发辅助工具类 📄 图解BlockingQueue阻塞队列
📄 消息队列那么多,为什么建议深入了解下RabbitMQ? 📄 高并发异步解耦利器:RocketMQ究竟强在哪里? 📄 Kafka必知必会18问:30+图带您看透Kafka
📄 洞悉MySQL底层架构:游走在缓冲与磁盘之间 📄 SQL运行内幕:从执行原理看调优的本质 📄 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法