JSP 2 的自定义标签

小吴
2023-01-02 / 0 评论 / 9 阅读 / 正在检测是否收录...

  在 JSP 规范的 1.1 版中增加了自定义标签库规范,自定标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能。
  为什么要使用自定义标签呢?主要是为了取代丑陋的 JSP 脚本。在 HTML 页面中插入 JSP 脚本有如下几个坏处:
  ➢ JSP 脚本非常丑陋,难以阅读。
  ➢ JSP 脚本和 HTML 代码混杂,维护成本高。
  ➢ HTML 页面中嵌入 JSP 脚本,导致美工人员难以参与开发。
  出于以上三个原因,Web 开发需要一种可在页面中使用的标签,这种标签具有和 HTML 标签类似的语法,但又可以完成 JSP 脚本的功能——这种标签就是 JSP 自定义标签。
  在 JSP 1.1 规范中开发自定义标签库比较复杂,JSP 2 规范简化了标签库的开发,在 JSP 2 中开发标签库只需如下几个步骤。
  ① 开发自定义标签处理类。
  ② 建立一个.tld 文件,每个.tld 文件对应一个标签库,每个标签库可包含多个标签
  ③ 在 JSP 文件中使用自定义标签。

开发自定义标签类

  在 JSP 页面使用一个简单的标签时,底层实际上由标签处理类提供支持,从而可以通过简单的标签来封装复杂的功能,从而使团队更好地协作开发(能让美工人员更好地参与 JSP 页面的开发)。
  自定义标签类应该继承一个父类:javax.servlet.jsp.tagext.SimpleTagSupport,除此之外,JSP 自定义标签类还有如下要求。
  ➢ 如果标签类包含属性,每个属性都有对应的 getter 和 setter 方法。
  ➢ 重写 doTag()方法,这个方法负责生成页面内容。
  下面开发一个最简单的自定义标签,该标签负责在页面上输出 HelloWorld。

public class HelloWorldTag extends SimpleTagSupport{
    // 重写doTag()方法,该方法为标签生成页面内容
    public void doTag() throws JspException,IOException{
        // 获取页面输出流,并输出字符串
        getJspContext().getOut().write("Hello World" + new java.util.Date());
    }
}

  上面这个标签处理类非常简单,它继承了 SimpleTagSupport 父类,并重写 doTag()方法,而 doTag()方法则负责输出页面内容。该标签没有属性,因此无须提供 setter 和 getter 方法。

建立 TLD 文件

  TLD 是 Tag Library Definition 的缩写,即标签库定义,文件的后缀是 tld,每个 TLD 文件对应一个标签库,一个标签库中可包含多个标签。TLD 文件也称为标签库定义文件。
  标签库定义文件的根元素是 taglib,它可以包含多个 tag 子元素,每个 tag 子元素都定义一个标签。通常可以到 Web 容器下复制一个标签库定义文件,并在此基础上进行修改即可。例如 Tomcat 8.0,在webapps\examples\WEB-INF\jsp2 路径下包含了一个 jsp2-example-taglib.tld 文件,这就是一个TLD文件的范例。
  将该文件复制到 Web 应用的 WEB-INF/路径,或 WEB-INF 的任意子路径下,并对该文件进行简单修改,修改后的 mytaglib.tld 文件代码如下。

<?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.0</tlib-version>
    <short-name>mytaglib</short-name>
    <!-- 定义该标签库的 URI -->    
    <uri>mytaglib</uri>
    <!-- 定义一个标签 -->
    <tag>
        <!-- 定义标签名 -->
        <name>helloWorld</name>
        <!-- 定义标签处理类 -->
        <tag-class>lee.HelloWorldTag</tag-class>
        <!-- 定义标签体为空 -->
        <body-content>empty</body-content>
    </tag>
</taglib>

  上面的标签库定义文件也是一个标准的 XML 文件,该 XML 文件的根元素是 taglib 元素,因此每次编写标签库定义文件时都直接添加该元素即可。

  taglib 下有如下三个子元素。
  ➢ tlib-version:指定该标签库实现的版本,这是一个作为标识的内部版本号,对程序没有太大的作用。
  ➢ short-name:该标签库的默认短名,该名称通常也没有太大的用处。
  ➢ uri:这个属性非常重要,它指定该标签库的 URI,相当于指定该标签库的唯一标识。如上面代码所示,JSP 页面中使用标签库时就是根据该 URI 属性来定位标签库的。
  除此之外,taglib 元素下可以包含多个 tag 元素,每个 tag 元素定义一个标签,tag 元素下允许出现如下常用子元素。
  ➢ name:该标签的名称,这个子元素很重要,JSP 页面中就是根据该名称来使用此标签的。
  ➢ tag-class:指定标签的处理类,毋庸置疑,这个子元素非常重要,它指定了标签由哪个标签处理类来处理。
  ➢ body-content:这个子元素也很重要,它指定标签体内容。该子元素的值可以是如下几个。
    ⚪ tagdependent:指定标签处理类自己负责处理标签体。
    ⚪ empty:指定该标签只能作为空标签使用。
    ⚪ scriptless:指定该标签的标签体可以是静态 HTML 元素、表达式语言,但不允许出现 JSP 脚本。
    ⚪ JSP:指定该标签的标签体可以使用 JSP 脚本。
  ➢ dynamic-attributes:指定该标签是否支持动态属性。只有当定义动态属性标签时才需要该子元素。

  定义了上面的标签库定义文件后,将标签库文件放在 Web 应用的 WEB-INF 路径或任意子路径下,Java Web 规范会自动加载该文件,则该文件定义的标签库也将生效。

使用标签库

  在 JSP 页面中确定指定的标签需要两点。
  ➢ 标签库 URI:确定使用哪个标签库。
  ➢ 标签名:确定使用哪个标签。
  使用标签库分成以下两个步骤。
  ① 导入标签库:使用 taglib 编译指令导入标签库,就是将标签库和指定前缀关联起来。
  ② 使用标签:在 JSP 页面中使用自定义标签。
  taglib 的语法格式如下:

<%@ taglib uri="tagliburi" prefix="tagprefix" %>

  其中 uri 属性指定标签库的 URI。这个 URI 可以确定一个标签库。而 prefix 属性指定标签库前缀,即所有使用该前缀的标签将由此标签库处理。
  使用标签的语法格式如下:

<tagPrefix:tagName tagAttribute="tagValue" ...>
<tagBody/>
</tagPrefix:tagName>

  如果该标签没有标签体,则可以使用如下语法格式:

  <tagPrefix:tagName tagAttribute="tagValue".../>

  上面使用标签的语法里都包含了设置属性值,前面介绍的 HelloWorldTag 标签没有任何属性,所以使用该标签只需用<mytag:helloWorld/>即可。其中 mytag 是 taglib 指令为标签库指定的前缀,而 helloWorld 是标签名。
  下面是使用 helloWorld 标签的 JSP 页面代码。

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!-- 导入标签库,指定 mytag 前缀的标签,由 UPI 为 mytaglib 的标签库处理 -->
<%@ taglib uri="mytaglib" prefix="mytag" %>
<!DOCTYPE html>
<html>
<head>
    <title>自定义标签示范</title>
</head>
<body bgcolor="#ffffc0">
<h2>下面显示的是自定义标签中的内容</h2>
<!-- 使用标签,其中 mytag 是标签前缀,根据 taglib 的编译指令,
        mytag 前缀将由 UPI 为 mytaglib 的标签库处理 -->
<mytag:helloWorld/><br/>
</body>
</html>

  以上页面中第二行代码指定了 URI 为 mytaglib 标签库的前缀为 mytag,倒数第三行代码表明使用 mytag 前缀对应标签库里的 helloWorld 标签。浏览该页面将看到如下图所示的效果。

简单标签

带属性的标签

  前面的简单标签既没有属性,也没有标签体,用法、功能都比较简单。实际上还有如下两种常用示签。
  ➢ 带属性的标签。
  ➢ 带标签体的标签。
  正如前面介绍的,带属性标签必须为每个属性提供对应的 setter 和 getter 方法。带属性标签的配置方法与简单标签也略有差别,下面介绍一个带属性标签的示例。

public class QueryTag extends SimpleTagSupport {
    // 定义成员变量来代表标签的属性
    private String driver;
    private String url;
    private String user;
    private String pass;
    private String sql;
    // 执行数据库访问的对象
    private Connection conn = null;
    private Statement stmt = null;
    private ResultSet rs = null;
    private ResultSetMetaData rsmd = null;

    // 各成员变量的 setter和getter 方法
    public void setDriver(String driver) {
        this.driver = driver;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }
    
    public void setSql(String sql) {
        this.sql = sql;
    }
    
    public String getDriver() {
        return (this.driver);
    }

    public String getUrl() {
        return (this.url);
    }

    public String getUser() {
        return (this.user);
    }

    public String getPass() {
        return (this.pass);
    }
    
    public String getSql() {
        return (this.sql);
    }
    
    public void doTag() throws JspException, IOException {
        try {
            // 注册驱动
            Class.forName(driver);
            // 获取数据库连接
            conn = DriverManager.getConnection(url, user, pass);
            // 创建 statement 对象
            stmt = conn.createStatement();
            // 执行查询
            rs = stmt.executeQuery(sql);
            rsmd = rs.getMetaData();
            // 获取列数目
            int columnCount = rsmd.getColumnCount();
            // 获取页面输出流
            Writer out = getJspContext().getOut();
            // 在页面输出表格
            out.write("<table border='1' bgColor='#9999cc' width='400'>");
            // 遍历结果集
            while (rs.next()) {
                out.write("<tr>");
                // 逐列输出查询到的数据
                for (int i = 1; i <= columnCount; i++) {
                    out.write("<td>");
                    out.write(rs.getString(i));
                    out.write("</td>");
                }
                out.write("</tr>");
            }
        } catch (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
            throw new JspException("自定义标签错误" + cnfe.getMessage());
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new JspException("自定义标签错误" + ex.getMessage());
        } finally {
            // 关闭结果集
            try {
                if (rs != null)
                    rs.close();
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException sgle) {
                sgle.printStackTrace();
            }
        }
    }
}

  上面这个标签稍微复杂一点,它包含了 5 个属性,如程序中粗体字代码所示(为标签处理类定义员变量即可代表标签的属性),程序需要为这5个属性提供 setter 和 getter 方法。
  该标签输出的内容依然由 doTag()方法决定,该方法会根据 SQL 语句查询数据库,并将查询结果显示在当前页面中。
  对于有属性的标签,需要为<tag.../>元素增加<attribute.../>子元素,每个 attribute 子元素定义一个标签属性。<attribute.../>子元素通常还需要指定如下几个子元素。
  ➢ name:设置属性名,子元素的值是字符串内容。
  ➢ required:设置该属性是否为必需属性,该子元素的值是 true 或 false。
  ➢ fragment:设置该属性是否支持 JSP 脚本、表达式等动态内容,子元素的值是 true 或 false。
  为了配置上面的 QueryTag 标签,需要在 mytaglib.tld 文件中增加如下配置片段。

<!-- 定义第二个标签 -->
<tag>
    <!-- 定义标签名 -->
    <name>query</name>
    <!-- 定义标签处理类 -->
    <tag-class>lee.QueryTag</tag-class>
    <!-- 定义标签体为空 -->
    <body-content>empty</body-content>
    <!--配置标签属性:driver -->
    <attribute>
        <name>driver</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
    <!-- 配置标签属性:url -->
    <attribute>
        <name>url</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
    <!-- 配置标签属性:user -->
    <attribute>
        <name>user</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
    <!-- 配置标签属性:pass -->
    <attribute>
        <name>pass</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
    <!-- 配置标签属性:sql -->
    <attribute>
        <name>sql</name>
        <required>true</required>
        <fragment>true</fragment>
    </attribute>
</tag>

  上面代码分别为该标签配置了 driver、url、user、pass 和 sql 五个属性,并指定这 5 个属性都是必需属性,而且属性值支持动态内容。
  配置完毕后,就可在页面中使用标签了,先导入标签库,然后使用标签。使用标签的JSP 页面片段如下。

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!-- 导入标签库,指定 mytag 前缀的标签,由 UPI 为 mytaglib 的标签库处理 -->
<%@ taglib uri="mytaglib" prefix="mytag" %>
<!DOCTYPE html>
<html>
<head>
    <title>自定义标签示范</title>
</head>
<body bgcolor="#ffffc0">
<h2>下面显示的是自定义标签中的内容</h2>
<!-- 使用标签,其中 mytag 是标签前缀,根据 taglib 的编译指令,
        mytag 前缀将由 UPI 为 mytaglib 的标签库处理 -->
<mytag:query driver="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/javaee"
    user="root"
    pass="root"
    sql="select * from news_inf"/><br/>
</body>
</html>

  在浏览器浏览该页面,效果如下图所示。

带属性的标签

  在 JSP 页面中只需要使用简单的标签,即可完成“复杂”的功能:执行数据库查询,并将查询结果在页面上以表格形式显示。这也正是自定义标签库的目的——以简单的标签,隐藏复杂的逻辑。
  当然,并不推荐在标签处理类中访问数据库,因为标签库是表现层组件,它不应该包含任何业务逻辑实现代码,更不应该执行数据库访问,它只应该负责显示逻辑。

带标签体的标签

  带标签体的标签,可以在标签内嵌入其他内容(包括静态的 HTML 内容和动态的 JSP 内容),通常用于完成一些逻辑运算,例如判断和循环等。下面以一个迭代器标签为示例,介绍带标签体标签的开发过程。
  一样先定义一个标签处理类,该标签处理类的代码如下。

public class IteratorTag extends SimpleTagSupport{
    // 标签属性,用于指定需要被迭代的集合
    private String collection;
    // 标签属性,指定迭代集合元素,为集合元素指定的名称
    private String item;
    // collection 和 item 的 setter 和 getter 方法
    public void setCollection(String collection) {
        this.collection = collection;
    }
    public void setItem(String item) {
        this.item = item;
    }
    public String getCollection() {
        return (this.collection);
    }
    public String getItem() {
        return (this.item);
    }
    // 标签的处理方法,标签处理类只需要重写doTag()方法
    public void doTag() throws JspException,IOException{
        // 从 page scope 中获取名为 collection 的集合
        Collection itemList = (Collection)getJspContext().getAttribute(collection);
        // 遍历集合
        for(Object s : itemList){
            // 将集合的元素设置到 page 范围内
            getJspContext().setAttribute(item, s);
            // 输出标签体
            getJspBody().invoke(null);
        }
    }
}

  上面的标签处理类与前面的处理类并没有太大的不同,该处理类包含两个成员变量(代表标签的属性),并为这两个成员量提供了 setter 和 getter 方法。标签处理类的 doTag()方法首先从 page 范围内获取了指定名称的 Collection 对象,然后遍历 Collection 对象的元素,每次遍历都调用了 getJspBody()方法,如程序中最后一行代码所示,该方法返回该标签所包含的标签体:JspFragmet 对象,执行该对象的 invoke()方法,即可输出标签体内容。该标签的作用是:遍历指定集合,每遍历一个集合元素,即输出标签体一次。
  因为该标签的标签体不为空,配置该标签时指定 body-content 为 scriptless,该标签的配置代码片段如下。

<!-- 定义第三个标签 -->
    <tag>
        <!-- 定义标签名 -->
        <name>iterator</name>
        <!-- 定义标签处理类 -->
        <tag-class>lee.IteratorTag</tag-class>
        <!-- 定义标签体不允许出现 JSP 脚本 -->
        <body-content>scriptless</body-content>
        <!-- 配置标签属性:collection -->
        <attribute>
            <name>collection</name>
            <required>true</required>
            <fragment>true</fragment>
        </attribute>
        <!-- 配置标签属性:item -->
        <attribute>
            <name>item</name>
            <required>true</required>
            <fragment>true</fragment>
        </attribute>
    </tag>

  上面的配置片段中<body-content.../>指定该标签的标签体可以是静态 HTML 内容,也可以是表达式语言,但不允许出现 JSP 脚本。
  为了测试在 JSP 页面中使用该标签的效果,下面先将一个 List 对象设置成 page 范围的属性,然后使用该标签来迭代输出 List 集合的全部元素。
  JSP 页面中使用该标签的代码片段如下。

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%@ page import="java.util.*" %>
<!-- 导入标签库,指定 mytag 前缀的标签,由 UPI 为 mytaglib 的标签库处理 -->
<%@ taglib uri="mytaglib" prefix="mytag" %>
<!DOCTYPE html>
<html>
<head>
    <title>带标签体的标签-迭代器标签</title>
</head>
<body>
    <h2>带标签体的标签-迭代器标签</h2>
    <%
    // 创建一个 List 对象
    List<String> a = new ArrayList<String>();
    a.add("小吴博客");
    a.add("xiaowu007.com");
    // 将 List 对象放入 page 范围内
    pageContext.setAttribute("a", a);
    %>
    <table border="1" bgcolor="#aaaadd" width="300">
        <!-- 使用迭代器标签,对 a 集合进行迭代 -->
        <mytag:iterator item="item" collection="a">
            <tr>
                <td>${pageScope.item}</td>
            </tr>
        </mytag:iterator>
    </table>
</body>
</html>

  上面的页面代码中<mytag:iterator.../>标签即可实现通过 iterator 标签来遍历指定集合,浏览该页面即可看到如下图所示的界面。

带迭代器的标签

  上图显示了使用 iterator 标签遍历集合元素的效果,从 iteratorTag.jsp 页面的代码来看,使用 iterator 标签遍历集合元素比使用 JSP 脚本遍历集合元素要优雅得多,这就是自定义标签的魅力。
  实际上 JSTL 标签库提供了一套功能非常强大的标签,例如普通的输出标签,就像刚刚介绍的选代器标签,还有用于分支判断的标签等,JSTL 都有非常完善的实现。

以页面片段作为属性的标签

  JSP 2 规范的自定义标签还允许直接将一段“页面片段”作为属性,这种方式给自定义标签提供了更大的灵活性。
  以“页面片段”为属性的标签与普通标签区别并不大,只有两个简单的改变。
  ➢ 标签处理类中定义类型为 JspFragment 的属性,该属性代表了“页面片段”。
  ➢ 使用标签库时,通过<jsp:attribute.../>动作指令为标签的属性指定值。
  下面的程序定义了一个标签处理类,该标签处理类中定义了一个 JspFragment 类型的属性,即表明该标签允许使用“页面片段”类型的属性。

public class FragmentTag extends SimpleTagSupport{
    private JspFragment fragment;
    // fragment 的 setter 和 getter 方法
    public void setFragment(JspFragment fragment){
        this.fragment = fragment;
    }
    public JspFragment getFragment(){
        return this.fragment;
    }
    @Override
    public void doTag() throws JspException,IOException{
        JspWriter out = getJspContext().getOut();
        out.println("<div style='padding:10px;border:lpx solid black;" + ";border-radius:20px'>");
        out.println("<h3>下面是动态传入的 JSP 片段</h3>");
        // 调用、输出“页面片段”
        fragment.invoke(null);
        out.println("</div>");
    }
}

  上面的程序中定义了 fragment 成员变量,该成员变量代表了使用该标签时的“页面片段”,配置该标签与配置普通标签并无任何区别,增加如下配置片段即可。

<tag>
        <!-- 定义标签名 -->
        <name>fragment</name>
        <!-- 定义标签处理类 -->
        <tag-class>lee.FragmentTag</tag-class>
        <!-- 指定该标签不支持标签体 -->
        <body-content>empty</body-content>
        <!-- 定义标签属性: fragment -->
        <attribute>
            <name>fragment</name>
            <required>true</required>
            <fragment>true</fragment>
        </attribute>
    </tag>

  从上面标签库的配置片段来看,这个自定义标签并没有任何特别之处,就是一个普通的带属性标签,该标签的标签体为空。
  由于该标签需要一个 fragment 属性,该属性的类型为 JspFragment,因此使用该标签时需要使用<jsp:attribute.../>动作指令来设置属性值,如以下代码片段所示。

<h2>下面显示的是自定义标签中的内容</h2>
<mytag:fragment>
    <jsp:attribute name="fragment">
    <%-- 使用 jsp:attribute 标签传入 fragment 参数 (该注释不能放在 fragment 内) --%>
        <!-- 下面是动态的 JSP 页面片段 -->
        <mytag:helloWorld/>
    </jsp:attribute>
</mytag:fragment>
<br/>
<mytag:fragment>
    <jsp:attribute name="fragment">
        <!-- 下面是动态的 JSP 页面片段 -->
        ${pageContext.request.remoteAddr}
    </jsp:attribute>
</mytag:fragment>

  上面的代码片段中<jsp:attribute.../>用于为标签的 fragment 属性赋值,第一个例子使用了另一个简单标签来生成页面片段;第二个例子使用了 JSP 2 的 EL 来生成页面片段;在浏览器中浏览该页面,将看到如下图所示的效果。

页面片段为属性的标签

动态属性的标签

  前面介绍带属性标签时,那些标签的属性个数是确定的,属性名也是确定的,绝大部分情况下这种带属性的标签能处理得很好,但在某些特殊情况下,需要传入自定义标签的属性个数是不确定的,属性名也不确定,这就需要借助于动态属性的标签了。
  动态属性标签比普通标签多了如下两个额外要求。
  ➢ 标签处理类还需要实现 DynamicAttributes 接口。
  ➢ 配置标签时通过<dynamic-attributes.../>子元素指定该标签支持动态属性。
  下面是一个动态属性标签的处理类。

public class DynaAttributesTag extends SimpleTagSupport implements DynamicAttributes{
    // 保存每个属性名的集合
    private ArrayList<String> keys = new ArrayList<String>();
    // 保存每个属性值的集合
    private ArrayList<Object> values = new ArrayList<Object>();
    @Override
    public void doTag() throws JspException, IOException {
        JspWriter out = getJspContext().getOut();
        // 此处只是简单地输出每个属性
        out.println("<ol>");
        for(int i = 0;i < keys.size(); i++ ){
            String key = keys.get(i);
            Object value = values.get(i);
            out.println("<li>" + key + " = " + value + "</li>");
        }
        out.println("</ol>");
    }
    @Override
    public void setDynamicAttribute(String uri, 
          String localName, Object value) throws JspException {
        // 添加属性名
        keys.add(localName);
        // 添加属性值
        values.add(value);
    }
}

  上面的标签处理类实现了 DynaAttributesTag 接口,就是动态属性标签处理类必须实现的接口,实现该接口必须实现 setDynaAttribute()方法,该方法用于为该标签处理类动态地添加属性名和属性值。标签处理类使用 ArrayList String 类型的 keys 属性来保存标签的所有属性名,使用 ArrayList Object 类型的 values 属性来保存标签的所有属性值。
  配置该标签时需要额外地指定<dynamic-attributes.../>子元素,表明该标签是带动态属性的标签。下面是该标签的配置片段。

<!-- 定义接受动态属性的标签 -->
<tag>
    <name>dynaAttr</name>
    <tag-class>lee.DynaAttributesTag</tag-class>
    <body-content>empty</body-content>
    <!-- 指定支持动态属性 -->
    <dynamic-attributes>true</dynamic-attributes>
</tag>

  上面的配置片段指定该标签支持动态属性。
  一旦定义了动态属性的标签,接下来在页面中使用该标签时将十分灵活,完全可以为该标签设置任意的属性,如以下页面代码所示。

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!-- 导入标签库,指定 mytag 前缀的标签,由 UPI 为 mytaglib 的标签库处理 -->
<%@ taglib uri="mytaglib" prefix="mytag" %>
<!DOCTYPE html>
<html>
<head>
    <title>自定义标签示范</title>
</head>
<body bgcolor="#ffffc0">
<h2>下面显示的是自定义标签中的内容</h2>
<h4>指定两个属性</h4>
<mytag:dynaAttr name="xiaowu" url="xiaowu123.com"/><br/>
<h4>指定四个属性</h4>
<mytag:dynaAttr 网站="小吴博客" 网址="xiaowu123.com"
        当前年份="2023年" 作者="小吴"/><br/>
</body>
</html>

  上面的页面代码中使用<mytag:dynaAttr.../>时十分灵活:可以根据需要动态地传入任意多个属性。不管传入多少个属性,这个标签都可以处理得很好,使用浏览器访问该页面将看到如下图所示的效果。

动态属性的标签

2

评论

博主关闭了当前页面的评论