JSP tld文件配置 自定义标签简单示例

本文代码转载自
《Servlet、JSP和Spring MVC初学指南》

有关自定义标签有一个比较全面的博文进行了较详尽的介绍,见:
http://blog.csdn.net/a154832918/article/details/8002064

那里对一些前一版本的标签有关类给出了介绍,但是应当使用较新的标签相关类
javax.servlet.jsp.tarext.SimpleTagSupport 其作为javax.servlet.jsp.tagext.SimpleTag
的接口实现类,的使用已经足够(simple tag handlers have the equivalent power of BodyTag,
But with a much simpler lifecycle and interface) 这里BodyTag就是支持body-context的接口
相应细节见上述博文链接。

下面首先给出的是一个没有body-context的简单例子,其使用了两种初始化attribute的方法,
基本上这里的自定义标签类就是一个简单的javaBean

无body的自定义标签的直接应用场景就是文本替换。

package customtag;


import java.io.IOException;
import java.util.StringTokenizer;

import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * Created by admin on 2017/2/17.
 */
public class DataFormatterTag extends SimpleTagSupport {
    private String header;
    private String items;

    public void setHeader(String header){this.header = header;}
    public void setItems(String items){this.items = items;}

    public void doTag()throws IOException, JspException{
        JspContext jspContext = getJspContext();
        JspWriter out = jspContext.getOut();

        out.print("<table style = 'border:1px solid green'>\n" +
                "<tr><td><span style='font-weight:bold'>" + header + "</span></td></tr>\n");
        StringTokenizer tokenizer = new StringTokenizer(items, ",");

        while(tokenizer.hasMoreTokens()){
            String token = tokenizer.nextToken();
            out.print("<tr><td>" + token + "</td></tr>\n");
        }

         out.print("</table>");

    }

}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="easy" uri="/WEB-INF/mytags.tld" %>
<html>
<head>
    <title>Testing DataFormttarTag</title>
</head>
<body>
    <easy:dataFormatter header="States" items = "Alabama,Alaska,Georgin,Florida"/>
    <br/>

    <easy:dataFormatter header="Countries">
        <jsp:attribute name = "items">
            US,UK,Canada,Korea
        </jsp:attribute>
    </easy:dataFormatter>


</body>
</html>

下面给出一个自定义SimpleTag实现的简单例子,(初步阶段是不太可能进行自定义SimpleTag
实现的,下面的解释仅仅是了解一下其作用机理)

package customtag;

/**
 * Created by admin on 2017/2/17.
 */
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;

public class MyFirstTag implements SimpleTag {
    JspContext jspContext;

    public void setParent(JspTag parent){System.out.println("setParent");}

    public JspTag getParent(){
        System.out.println("getParent");
        return null;
    }

    public void doTag()throws IOException, JspException{
        System.out.println("doTag");
        jspContext.getOut().print("This is my first tag.");
    }

    public void setJspContext(JspContext jspContext){
        this.jspContext = jspContext;
    }

    public void setJspBody(JspFragment body){
        System.out.println("setJspBody");
    }

}

(省略get部分)其中setParent方法是为了构造标签的嵌套结构所提供的接口,JspTag类是若干标签
类的基类。
SimpleTagSupport中的实现是

public void setParent(JspTag parent) {
                                   this.parentTag = parent;
                               }

由于JspContext用于内容输出,故相应的方法的作用是明显的。
对于JspBody的相关方法,这里以JspFragment为参数,其为相应自定义标签内容的实体化类,
获得相应实例的方法为getJspBody() 当得到相应实例后可以通过调用invoke方法进行标签
内容的输出。
invoke(Writer out)
    Executs the fragment and directs(指挥) all outputs to the given Writer, or
     the JspWriter returned by the getOut() method of JspContext associated with
     the fragment if out is null.

一些示例是有关使用这种方法将 自定义标签的的内部内容通过invoke进行输出的
如以下链接:
http://www.cnblogs.com/xdp-gacl/p/3916968.html
及该博客的一些其它示例

当然能想到的一些应用为在其它的一些自定义标签类中调用该自定义标签的body进行输出。

下面是其对应的jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="easy" uri ="/WEB-INF/mytags.tld" %>
<html>
<head>
    <title>Testing my first tag</title>
</head>
<body>
Hello!!!
<easy:firstTag></easy:firstTag>

</body>
</html>

关于JspFragment invoke调用的例子也可见下例,这里要进行的就是构造select域,
使用了setAttribute方法,在前一篇博文 JSP 渲染简单示例 中利用request传递attribute
也用了类似的方法。(只不过这里定义的是自定义标签的属性)
package customtag;

/**
 * Created by admin on 2017/2/17.
 */

import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class selectElementTag extends SimpleTagSupport {
    private String[] countries = {"Austrialia", "Brazial", "China"};

    public void doTag()throws IOException, JspException{
        JspContext jspContext = getJspContext();
        JspWriter out = jspContext.getOut();
        out.print("<select>\n");
        for(int i = 0;i < 3;i++){
            jspContext.setAttribute("value", countries[i]);
            getJspContext().setAttribute("text", countries[i]);
            getJspBody().invoke(null);
        }
        out.print("</select>");

    }

}

相应jsp文件如下,注意开启EL表达式


<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="easy" uri="/WEB-INF/mytags.tld" %>
<html>
<head>
    <title>Testing SelectElementFormatterTag</title>
</head>
<body>
    <easy:select>
        <option value="${value}">${text}</option>
    </easy:select>

</body>
</html>

最后给出上述三个例子的配置文件,
这里由于第三个例子在自定义标签中使用了EL表达式来设定,故相应配置中的body-content属性
为scriptless(接受文本、EL、和JSP动作作为内容)

required指定属性是否为必须的。

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/j2ee/dtds/web-jsptaglibrary_2_1.xsd"
        version="2.1">

    <tlib-version>
        1.0
    </tlib-version>
    <short-name>My First Taglib Exampole</short-name>

    <tag>
        <name>dataFormatter</name>
        <tag-class>customtag.DataFormatterTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>header</name>
            <required>true</required>
        </attribute>
        <attribute>
            <name>items</name>
            <required>true</required>
        </attribute>
    </tag>

    <tag>
        <name>firstTag</name>
        <tag-class>customtag.MyFirstTag</tag-class>
        <body-content>empty</body-content>
    </tag>


    <tag>
        <name>select</name>
        <tag-class>customtag.selectElementTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>
</taglib>

相较于上述自定义标签,个人感觉较原生的JSP较复杂(配置),
而且从使用上,可以看到 其作用就是将JSP标签赋予类的一些相关功能,
这里是将一部分 JSP相应的标签内容的生成部分放到自定义标签类中,
属于类实例化的 内容生成方法

与之相对的 还有一种方法 是使用类的静态方法 即自定义函数标签类
要声明的是 对于 自定义函数标签类 从使用角度来说由于EL表达式仅仅能调用类
的静态方法,故对于这些类仅仅声明静态方法 就可以了
下面是一个简单例子

定义静态方法的类
package function;

/**
 * Created by admin on 2017/2/20.
 */
public class StringFunction {

    public static String reverseString(String s){
        return (new StringBuffer(s)).reverse().toString();
    }

}

tld配置文件
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/j2ee/dtds/web-jsptaglibrary_2_1.xsd"
        version="2.1">

        <uri>http://example.com/taglib/function</uri>

<tlib-version>
    1.0
</tlib-version>
    <short-name>
        Function tag examples
    </short-name>

    <function>
        <name>reverseString</name>
        <function-class>function.StringFunction</function-class>
        <function-signature>
            java.lang.String reverseString(java.lang.String)
        </function-signature>

    </function>



</taglib>

jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="f" uri ="/WEB-INF/functiontags.tld"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${f:reverseString("Hello World")}
</body>
</html>

上述tld配置文件的第一行 所标注的uri标签的使用见下例
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="f" uri ="http://example.com/taglib/function" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${f:reverseString("Welcome")}
</body>
</html>

有了uri映射后就可以对于多个jsp文件实现相同的tld渲染配置。
关于使用自定义函数标签的其它简单例子见
http://www.cnblogs.com/edwardlauxh/archive/2010/05/19/1918589.html




                
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值