自定义标签库jsp

建立TLD文件

我们写Servlet的时候,会在web.xml中加入定义的Servlet类和URL之间的映射。同理,我们定义了标签类,也需要一个配置文件,将自定义标签和对应的标签类关联起来。在定义自定义标签时,这个配置文件叫做标签库定义文件,是以tld后缀结尾的,每个TLD文件对应一个标签库,一个标签库中可包含多个标签。

标签库定义文件的根元素是taglib,它可以包含多个tag子元素,每个tag子元素都定义一个标签。我们需要将tld文件保存到Web应用的WEB-INF/路径,或者WEB-INF的任意子路径下。

以下就是我定义的一个简单的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/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  version="2.0">

  <description>Test 1.0</description>
  <tlib-version>1.0</tlib-version>
  <short-name>jtlib</short-name>
  <uri>http://www.jellythink.com/jtlib/</uri>

  <!-- 定义一个标签 -->
  <tag>
    <!-- 定义标签名 -->
    <name>jtTag</name>
    <!-- 定义标签处理类 -->
    <tag-class>com.jellythink.practise.TestTag</tag-class>
    <!-- 定义标签体内容为空 -->
    <body-content>empty</body-content>
  </tag>
</taglib>

标签库定义文件是一个XML文件,该XML文件的根元素是taglib元素。taglib主要有以下几个子元素:

  • description,对该tld文件的一些描述性的信息
  • tlib-version,指定该标签库实现的版本,这是一个作为标识的内部版本号,对程序没有太大的作用
  • short-name,标签库的默认短名,没有太大的作用
  • uri,这个属性非常重要,它指定该标签库的URI,相当于指定该标签库的唯一标识。JSP页面中使用标签库时就是根据该URI属性来定位标签库的

接下来,taglib元素下可以包含多个tag元素,每个tag元素定义一个标签,tag元素主要有以下子元素:

  • name,指定标签的名字,JSP页面中就是根据该名称来使用此标签的,所以该子元素非常重要
  • tag-class,指定标签的处理类,它指定了标签由哪个标签处理类来处理,该子元素极其重要
  • body-content,指定标签体的内容,该子元素非常重要,它主要可以取以下几个值:
    • tagdependent,指定标签处理类自己负责处理标签体
    • empty,该标签只能作为空标签来使用
    • scriptless,指定该标签的标签体可以是静态HTML元素、表达式语言,但不能是JSP脚本
    • dynamic-attributes,指明该标签是否支持动态属性。只有定义动态属性标签时才需要该子元素

以上就是标签库定义文件的编写规范,以及编写过程中需要注意的内容事项。编写好标签库定义文件以后,将标签库文件放在Web应用的WEB-INF路径,或者任意子路径下,Java Web会自动加载该文件,该文件定义的标签库也将生效。

使用标签库

标签库处理类定义好了,标签库定义文件也写好了,接下来就该小试牛刀了,看看在JSP中到底该怎么使用我们自定义的标签。

在JSP页面中使用标签库需要注意以下两点:

  • 标签库URI:确定使用哪个标签库
  • 标签名:确定使用哪个标签

具体使用标签库主要分为以下两个步骤:

  1. 导入标签库;使用taglib编译指令导入标签库,就是将标签库和指定前缀关联起来
  2. 使用标签;在JSP页面中使用自定义标签

下面通过一个简单的JSP来说明如何使用自定义标签,JSP页面代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page pageEncoding="UTF-8"%>

<!-- 导入标签库 -->
<%@ taglib uri="http://www.jellythink.com/jtlib/" prefix="jt" %>

<!DOCTYPE>
<html>
<head>
<title>页面一</title>
</head>
<body>
    <!-- 使用自定义标签  -->
    <!-- 输出:http://www.jellythink.com 果冻想-一个原创技术文章分享网站  -->
    <jt:jtTag />
    <jt:jtTag />
</body>
</html>

总结到这里,对于如何定义一个简单的标签,以及如何使用这个简单的自定义标签,大家心里应该都有数了,接下来看看自定义标签的一些高级用法,而这些高级用法才是开发中真正经常碰到的。

带属性的标签

很多时候,单纯的一个标签根本无法满足我们的需要。我们需要在标签中添加一些属性,通过设置的这些属性值,我们可以进行更丰富的操作,比如执行属性值中指定的SQL语句,从而返回并显示查询结果。下面就来说说如何在自定义标签中添加属性的功能。

首先,带属性的标签必须要为每个属性提供对应的setter和getter方法;例如,我们的自定义标签将会有三个属性,分别是:name、price和store。那么我们对应的标签处理类会变成下面这个样子:

package com.jellythink.practise;

import java.io.IOException;

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

public class TestTag extends SimpleTagSupport
{
    // 标签定义的属性
    private String name;
    private String price;
    private String store;

    // 需要为每个属性定义setter和getter方法
    public void setName(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return this.name;
    }

    public void setPrice(String price)
    {
        this.price = price;
    }

    public String getPrice()
    {
        return this.price;
    }

    public void setStore(String store)
    {
        this.store = store;
    }

    public String getStore()
    {
        return this.store;
    }

    public void doTag() throws JspException, IOException
    {
        JspWriter out = getJspContext().getOut();
        out.write("书名:" + name);
        out.write("价格:" + price);
        out.write("书店:" + store);
    }
}

每个属性都必须要有对应的setter和getter方法,这是不能少的。标签对应的处理类进行了对应的变更;同理,对于标签库定义文件也要进行对应的修改,需要为<tag... />元素增加<attribute... />子元素,每个attribute子元素定义一个标签属性。在定义attribute元素时,需要为其指定以下几个子元素:

  • name,设置属性名;在使用自定义标签时,就是通过该名指定属性名
  • required,设置该属性是否为必须属性,取值为true或false
  • fragment,设置该属性是否支持JSP脚本、表达式等动态内容,取值为true或false

为此,我们的标签库定义文件就要修改为如下这样:

<?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/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  version="2.0">

  <description>Test 1.0</description>
  <display-name>Test TLD</display-name>
  <tlib-version>1.0</tlib-version>
  <short-name>jtlib</short-name>
  <uri>http://www.jellythink.com/jtlib/</uri>

  <!-- 定义一个标签 -->
  <tag>
    <!-- 定义标签名 -->
    <name>jtTag</name>
    <!-- 定义标签处理类 -->
    <tag-class>com.jellythink.practise.TestTag</tag-class>
    <!-- 定义标签体内容为空 -->
    <body-content>empty</body-content>

    <!-- 配置name属性 -->
    <attribute>
        <name>name</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>

    <!-- 配置price属性 -->
    <attribute>
        <name>price</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>

    <!-- 配置store属性 -->
    <attribute>
        <name>store</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
  </tag>
</taglib>

接下来,我们就可以在JSP中使用这个带有属性定义的自定义标签了,具体代码如下:

<jt:jtTag name="Java编程思想" price="75.58" store="三味书屋" /> <br/>
<jt:jtTag name="看见" price="25.10" store="书海书屋" /> <br/>
<jt:jtTag name="狼图腾" price="23.00" store="国家图书馆" /> <br/>

具体输出如下:

书名:Java编程思想价格:75.58书店:三味书屋 
书名:看见价格:25.10书店:书海书屋 
书名:狼图腾价格:23.00书店:国家图书馆 

这就是带有属性的自定义标签。

带标签体的标签

可以看到,上面自定义的标签都是没有任何标签体的,都是一个简单的标签。那么如果我们希望标签中带有标签体,这又如何完成呢?

对于带标签体的自定义标签,我们可以在标签内嵌入静态的HTML内容和动态的JSP内容,通常用于循环输出一些内容。下面就通过一个简单的例子进行说明。

标签类的处理代码如下:

package com.jellythink.practise;

import java.io.IOException;
import java.util.Collection;

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

public class TestTag extends SimpleTagSupport
{
    // 标签定义的属性
    private String collection;
    private String item;

    public void setCollection(String collection)
    {
        this.collection = collection;
    }

    public String getCollection()
    {
        return this.collection;
    }

    public void setItem(String item)
    {
        this.item = item;
    }

    public String getItem()
    {
        return this.item;
    }


    public void doTag() throws JspException, IOException
    {
        JspContext context = getJspContext();

        // 根据属性值,获得设置的对象
        Collection itemList = (Collection)context.getAttribute(collection);
        for (Object s : itemList)
        {
            // 设置属性值,供标签体使用
            context.setAttribute(item, s);

            // 输出标签体,这个是重点
            getJspBody().invoke(null);
        }
    }
}

标签库定义文件:

<?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/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  version="2.0">

  <description>Test 1.0</description>
  <display-name>Test TLD</display-name>
  <tlib-version>1.0</tlib-version>
  <short-name>jtlib</short-name>
  <uri>http://www.jellythink.com/jtlib/</uri>

  <!-- 定义一个标签 -->
  <tag>
    <!-- 定义标签名 -->
    <name>jtTag</name>
    <!-- 定义标签处理类 -->
    <tag-class>com.jellythink.practise.TestTag</tag-class>
    <!-- 定义标签体内容为空 -->
    <body-content>scriptless</body-content>

    <!-- 配置属性 -->
    <attribute>
        <name>collection</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>

    <attribute>
        <name>item</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
  </tag>
</taglib>

对于标签库定义文件来说,主要是<body-content>字段的值需要设置为scriptless。最重要的是JSP页面里如何使用带有标签体的自定义标签,具体代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>

<!-- 导入标签库 -->
<%@ taglib uri="http://www.jellythink.com/jtlib/" prefix="jt" %>

<!DOCTYPE>
<html>
<head>
<title>页面一</title>
</head>
<body>
    <%
    // 创建一个List对象
    List<String> obj = new ArrayList<String>();
    obj.add("博客园");
    obj.add("开源中国");
    obj.add("果冻想");
    pageContext.setAttribute("collection", obj);
    %>

    <jt:jtTag collection="collection" item="item">
        ${pageScope.item} <br />
    </jt:jtTag>

</body>
</html>

由于JSP主要作为表现层,上面只是通过一个简单的例子来说明如何表现数据;很多时候,我们后台返回一个数据集合,我们就可以通过这种方式来表现数据。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值