自定义标签

JSP自定义标签是一种扩展JSP功能的高级技巧,它允许开发者定义自己的标签,以便在JSP页面中重复使用。自定义标签使得在JSP中可以使用更高级的抽象,从而提高了代码的可重用性、可维护性和可读性,开发自定义标签包含如下步骤:

  1. 开发自定义标签处理类
  2. 建立TLD文件,它本质是一个XML格式的标签库描述文件,每个.tld对应一个标签库,每个标签库可以包含多个标签
  3. JSP中引入并使用自定义标签

这篇笔记我们介绍如何在JSP中自定义标签。

实现带属性自定义标签

自定义标签需要有一个对应的Java类包含自定义标签的代码逻辑,这个类需要实现JspTag接口,我们一般直接继承SimpleTagSupport类。自定义标签中最重要的方法就是doTag(),其中包含了自定义标签的渲染逻辑。

HelloTag.java

package com.gacfox.demoweb.demo.taglib;

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

public class HelloTag extends SimpleTagSupport {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().write("hello," + name);
    }
}

代码中,name是该标签的一个属性,doTag()方法则是具体的渲染逻辑,这里我们通过getJspContext()方法获取JSP上下文并写入一些内容。

mytaglib.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>My demo tag lib</description>
    <tlib-version>1.0</tlib-version>
    <short-name>MyTagLib</short-name>
    <uri>https://gacfox.com/mytaglib</uri>

    <tag>
        <description>show hello</description>
        <name>hello</name>
        <tag-class>com.gacfox.demoweb.demo.taglib.HelloTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>name</name>
            <required>true</required>
        </attribute>
    </tag>
</taglib>

TLD包含一些重要的属性设置。

  • tlib-version 标签库的版本号
  • short-name 标签库的默认短名,没太大用处
  • uri 标签库的唯一标示,用于JSP页面中标签库引入
  • tag 标签定义
  • name 引用该标签的标签名
  • tag-class 标签定义的类
  • body-content 指定标签体内容

TLD文件需要被放置在WEB-INF或其子目录下,通常我们会建立一个WEB-INF/tlds目录来放置所有的自定义标签库TLD。上述XML代码中,我们配置了标签库的描述信息、标签对应的类、标签的属性字段等。

引入自定义标签库需要通过uri来关联,下面是一个例子。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="m" uri="https://gacfox.com/mytaglib"%>
<html>
<head>
    <title>demo tag</title>
</head>
<body>
<m:hello name="admin" />
</body>
</html>

上面代码中我们设置了自定义标签库的前缀是m,我们自定义的标签hello即可通过<m:hello>引用,上述代码运行后会输出hello,admin字样。

实现带标签体自定义标签

前面的例子比较简单,我们的自定义标签只有一个属性字段,而没有标签体,带有标签体的自定义标签会稍微复杂一些。下面例子中,我们编写了一个用于迭代List对象的自定义标签。

package com.gacfox.demoweb.demo.taglib;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.util.Collection;

public class IterTag extends SimpleTagSupport {
    /**
     * 迭代集合的属性名
     */
    private String collectionStr;
    /**
     * 用于迭代的元素
     */
    private String item;

    public String getCollectionStr() {
        return collectionStr;
    }

    public void setCollectionStr(String collectionStr) {
        this.collectionStr = collectionStr;
    }

    public String getItem() {
        return item;
    }

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

    @Override
    public void doTag() throws JspException, IOException {
        PageContext pageContext = (PageContext) getJspContext();
        Collection collection = (Collection) pageContext.getRequest().getAttribute(collectionStr);
        for (Object o : collection) {
            getJspContext().setAttribute(item, o);
            getJspBody().invoke(null);
        }
    }
}

该标签有两个属性,collectionStr用于指定迭代集合的变量名,item用于指定迭代变量的变量名,doTag()中我们编写了循环渲染的逻辑,其中invoke()方法用于执行包含在自定义标签体中的JSP片段,对于带标签体的自定义标签该方法至关重要。

该标签的TLD定义如下:

<tag>
    <name>iter</name>
    <tag-class>com.gacfox.demoweb.demo.taglib.IterTag</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
        <name>collectionStr</name>
        <required>true</required>
    </attribute>
    <attribute>
        <name>item</name>
        <required>true</required>
    </attribute>
</tag>

在JSP页面中我们可以通过如下方式使用该自定义标签。

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="m" uri="https://gacfox.com/mytaglib" %>
<html>
<head>
    <title>tag demo</title>
</head>
<body>
<%
    List<String> myList = new ArrayList<>();
    myList.add("Item 1");
    myList.add("Item 2");
    request.setAttribute("myList", myList);
%>
<table>
    <m:iter collectionStr="myList" item="i">
        <tr>
            <td>${i}</td>
        </tr>
    </m:iter>
</table>
</body>
</html>

上述代码最终会被渲染为一个HTML表格。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap