自定义Tag标签

我们在jsp中总是会用到一些标签,比如的一系列标签什么的。
但是有的时候我们希望用一些现有标签库没有的东西,可不可以自己定义一个标签呢?
当然可以!

Tag简介

一个tag就是一个普通的java类,它唯一特别之处是它必须继承 TagSupport或者BodyTagSupport类。这两个类提供了一些方法,负责jsp页面和你编写的类之间的交互,例如输入,输出。而这两个类 是由jsp容器提供的,无须开发人员自己实现。

如果我们想要自己定义一个tag需要做哪些工作呢?
“特别的工作”通常有以下几个步骤:

1)提供属性的set方法,此后这个属性就可以在jsp页面设置。以jstl标签为例 <c:out value=""/>,这个value就是jsp数据到tag之间的入口。所以tag里面必须有一个setValue方法,具体的属性可以不叫value。
这个“value”的名称是在tld里定义的。取什么名字都可以,只需tag里提供相应的set方法即可。
2)处理 doStartTag 或 doEndTag 。这两个方法是 TagSupport提供的。 还是以<c:out value=""/>为例,当jsp解析这个标签的时候,在“<”处触发 doStartTag 事件,在“>”时触发 doEndTag 事件。通常在 doStartTag 里进行逻辑操作,在 doEndTag 里控制输出。
3)编写tld文件。
4)在jsp页面导入tld。

这里提到了tld文件,那我们就看看这又是个什么文件。

扩展名为tld的文件是存放标签名字和类的映射用的。
标签库,他把页面标签和后面的Java类影射起来.减少了页面中的代码。使页面清晰。其实标签最后还是被解释成后台的Java代码。
原理是,在用户在jsp页面中使用标签时,系统首先会先到xml文件中的 标签中的这两对标签找到相对应的扩展名为tld文件,然后在 tld文件中的映射再找到相对应的taglib类。

小demo

GitHub项目地址

项目结构图

自定义Tag标签_第1张图片

从底层一点一点介绍吧。
首先是我们自定义的tag处理类
DateTag

package com.yubotao.Tag;


import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * Created by Administrator on 2017/08/18.
 */
public class DateTag extends TagSupport {

    private String value;

    @Override
    public int doStartTag() throws JspException {
        String vv = "" + value;
        long time = Long.valueOf(vv);
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String s = dateFormat.format(c.getTime());
        try{
            pageContext.getOut().write(s);
        }catch (IOException e){
            e.printStackTrace();
        }

        return super.doStartTag();
    }

    public void setValue(String value){
        this.value = value;
    }

}

这里面主要的逻辑就是将传入的Long型数据经过一番处理,最后转化成date格式展示时间。

整个类里面最关键的一行代码就是

pageContext.getOut().write(s);

这句的意思就是使用pageContext对象向jsp页面写入输入流,也就是我们刚转换的date格式的String字符串。

接下来我们需要定义tld文件
dateTag.tld


<taglib>
    <tlib-version>1.0tlib-version>
    <jsp-version>1.2jsp-version>

    <tag>
        <name>datename>
        <tag-class>com.yubotao.Tag.DateTagtag-class>
        <body-content>JSPbody-content>
        <attribute>
            <name>valuename>
            <required>truerequired>
            <rtexprvalue>truertexprvalue>
        attribute>
    tag>
taglib>

这里IDEA会在那里报红,不过并不影响使用。
我们主要在标签中对各个标签进行定义,比如就是我们使用的标签名,在jsp页面有对应;就是我们自定义的tag类;设置为JSP,表示接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。
BodyContent类继承了JspWriter,同时又对JspWriter实现了包装模式(wrapper),实质就是JspWriter的层层包装,你可以把这种结构想象成一个洋葱。这个有点深入了,可以参考这篇文章,这里暂不介绍。

在配置完tld文件后,我们还需要在web.xml中引入tld文件。
web.xml

 <jsp-config>
    <taglib>
      <taglib-uri>/tagstaglib-uri>
      <taglib-location>/WEB-INF/tld/dateTag.tldtaglib-location>
    taglib>
  jsp-config>

这里对jsp中的taglib进行了定义,定义了,这个在jsp页面中会用到,然后定义了,这里面的值就是你的tld文件路径。

然后看一下在jsp页面中如何引用的

<%@taglib uri="/tags" prefix="date"%>
<date:date value="${date}"/>

这里的uri和之前的web.xml文件中定义的对应上了。prefix中的值和中的第一个”date”对应上了,而第二个”date”对应的是之前tld文件中设置的下的值。

就此我们就完成了自定义标签的使用,看一下效果图。
自定义Tag标签_第2张图片

总结

最后梳理一下自定义标签的处理过程:
首先如果我们的jsp页面有一个自定义标签;然后会通过jsp中的中对应的uri去找我们自定义的tld文件,而这步是通过web.xml文件中对于taglib标签的配置完成的;然后再通过tld找到对应的自定义tag处理类,因为我们自定义的tag标签做的最后一件事就是打印,所以感觉还有交互,其实并没有了,到这里该tag标签工作就完毕了。

通过如上的梳理,我们自定义tag标签的时候需要做的就是:
1.自定义tag处理类;
2.配置对应的tld文件;
3.在web.xml中对tld文件进行配置;
4.在jsp中引用到自定义的tag标签。

你可能感兴趣的:(编程之路)