由自定义标签了解标签是如何起作用的

来源:互联网 发布:bf是什么意思淘宝 编辑:程序博客网 时间:2024/06/15 11:31

由自定义标签了解标签是如何起作用的


标签配置文件 tld

talk is cheap show me the code:

<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"    version="2.1">  <!-- 标签库的版本号 -->  <tlib-version>1.2</tlib-version>  <!-- 标签库的简写名称 -->  <short-name>mytag</short-name>  <!-- 标签库对应的唯一uri -->  <uri>http://heyahui/taglib</uri>  <!-- 自定义的标签 -->  <tag>    <!-- 标签名称 -->    <name>hello</name>    <!-- 实现标签功能的类的具体路径 -->    <tag-class>a_tag.HelloTag</tag-class>    <!-- 标签体内容的限制 scriptless:不支持jsp empty:内容为空 tagdependent:支持jsp,但当作文本 JSP:支持jsp,不建议 -->    <body-content>scriptless</body-content>    <!-- 标签中的属性 -->    <attribute>        <!-- 属性的名字 -->        <name>num</name>        <!-- 属性是否是必须的 -->        <required>false</required>        <!-- 属性是否支持EL表达式 -->        <rtexprvalue>false</rtexprvalue>    </attribute>  </tag></taglib>

有了这个配置文件,我们下面只需要一个类来实现标签的具体功能就行了

标签的实现类

talk is cheap show me the code:

package a_tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class HelloTag extends SimpleTagSupport {    // 标签属性的具体实现    private int num;    // 标签属性的获取方法    public void setNum(int num) {        this.num = num;    }    @Override    // 该方法是用于标签的具体功能实现的    public void doTag() throws JspException, IOException {        // 输出标签中的内容但无法对内容修改        this.getJspBody().invoke(null);        // 获取标签的内容并修改后输出        JspFragment jspBody = this.getJspBody();        StringWriter writer = new StringWriter();        jspBody.invoke(writer);        String content = writer.toString();        content = content.subString(0,1);        this.getContext().getOut().write(content);        /*         *这里讲一下直接输出的原理         *invoke()方法的参数为null时其实是默认将JspWriter作为其对象的,并调用它的write()方法         *直接将标签内容传给页面的输出流,我们无法做修改         *要想修改这个内容,必须用一个其它流去接收它,然后再做修改         */    }}

上面的代码省略了一些标签类的其它方法,这些方法主要是用于标签的具体创建等生命周期的,都在超类中进行了重写,所以我们一般只需要重写具体的逻辑即可

案例参考

这里,我们来模仿几个主流的标签的实现
talk is cheap show me the code

if 标签

<!-- tld文件中的标签部分 -->  <!-- if -->  <tag>    <name>if</name>    <tag-class>a_tag.IfTag</tag-class>    <body-content>scriptless</body-content>    <attribute>        <name>test</name>        <required>true</required>        <rtexprvalue>true</rtexprvalue>             </attribute>  </tag>
package a_tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class IfTag extends SimpleTagSupport {    private boolean test;    public void setTest(boolean test) {        this.test = test;    }    @Override    public void doTag() throws JspException, IOException {        if (testValue) {            this.getJspBody().invoke(null);        }    }}

choose 标签

<!-- tld文件中的标签部分 -->  <!-- choose -->  <tag>    <name>choose</name>    <tag-class>a_tag.ChooseTag</tag-class>    <body-content>scriptless</body-content>  </tag>  <!-- when -->  <tag>    <name>when</name>    <tag-class>a_tag.WhenTag</tag-class>    <body-content>scriptless</body-content>    <attribute>        <name>test</name>        <required>true</required>        <rtexprvalue>true</rtexprvalue>    </attribute>  </tag>  <!-- otherwise -->  <tag>    <name>otherwise</name>    <tag-class>a_tag.OtherwiseTag</tag-class>    <body-content>scriptless</body-content>  </tag>
package a_tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class ChooseTag extends SimpleTagSupport {    private boolean flag;    public boolean isFlag() {        return flag;    }    public void setFlag(boolean flag) {        this.flag = flag;    }    @Override    public void doTag() throws JspException, IOException {        this.getJspBody().invoke(null);    }}
package a_tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class WhenTag extends SimpleTagSupport {    private boolean test;    public void setTest(boolean test) {        this.test = test;    }    @Override    public void doTag() throws JspException, IOException {        if (test) {            this.getJspBody().invoke(null);        }         ((ChooseTag) this.getParent()).setFlag(test);    }}
package a_tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class OtherwiseTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException, IOException {        if (!((ChooseTag) this.getParent()).isFlag()) {            this.getJspBody().invoke(null);        }    }}

foreach标签

<!-- tld文件中的标签部分 -->  <!-- foreach -->  <tag>    <name>foreach</name>    <tag-class>a_tag.ForeachTag</tag-class>    <body-content>scriptless</body-content>    <attribute>        <name>items</name>        <required>true</required>        <rtexprvalue>true</rtexprvalue>    </attribute>    <attribute>        <name>var</name>        <required>true</required>        <rtexprvalue>false</rtexprvalue>    </attribute>  </tag>
package a_tag;import java.io.IOException;import java.util.List;import java.util.Map;import java.util.Set;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.SimpleTagSupport;public class ForeachTag extends SimpleTagSupport {    private Object items;    private String var;    public void setItems(Object items) {        this.items = items;    }    public void setVar(String var) {        this.var = var;    }    @Override    public void doTag() throws JspException, IOException {        PageContext context = (PageContext) this.getJspContext();        if (items instanceof List) {            List list = (List) items;            for (Object object : list) {                context.setAttribute(var, object);                this.getJspBody().invoke(null);            }        } else if (items instanceof Map) {            Map<String, Object> map = (Map) items;            for (Map.Entry entry : map.entrySet()) {                context.setAttribute(var, entry);                this.getJspBody().invoke(null);            }        }    }}
0 0
原创粉丝点击