JSP 自定义标签 ( SimpleTagSupport )

一般情况下 JSP 内置的标签和 JSTL 里的标签已经够用了,很少有场景需要自定义 JSP 标签了

但有的时候,就是需要自己去自定义一个 JSP 标签

自定义标签

自定义标签是用户定义的 JSP 语言元素

当 JSP 页面包含一个自定义标签时将被转化为 Servlet,标签转化为对被称为 tag handler的对象的操作,即当 Sservlet 执行时 Web container 调用那些操作

JSP 标签扩展可以让我们创建新的标签并且可以直接插入到一个 JSP 页面

JSP 2.0 规范中引入 Simple Tag Handlers 来编写这些自定义标签

我们可以继承 SimpleTagSupport 类并重写 doTag() 方法来开发一个最简单的自定义标签

创建 "Hello" 标签

接下来我们自定义一个叫做 <ex:Hello> 的标签

标签语法为:

<ex:Hello />

创建自定义的 JSP标签,首先需要创建处理标签的 Java 类

因此,我们创建一个 HelloTag 类

// author: 简单教程(www.twle.cn)
// Copyright © 2015-2065 www.twle.cn. All rights reserved.

package cn.twle.demo;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;

public class HelloTag extends SimpleTagSupport
{
    public void doTag() throws JspException, IOException
    {
        JspWriter out = getJspContext().getOut();
        out.println("Hello Custom Tag!<br/>");
        out.println("Nice to see you,简单教程");
  }
}

我们重写了 doTag() 方法,并使用 getJspContext()方法获取当前的 JspContext 对象,然后将 " Hello Custom Tag!" 等字符串传递给 JspWriter 对象

编译上面的类,并将其复制到环境变量 CLASSPATH 目录中

最后,创建如下标签库

webapp\WEB-INF\custom.tld

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD</short-name>
  <tag>
    <name>Hello</name>
    <tag-class>cn.twle.demo.HelloTag</tag-class>
    <body-content>empty</body-content>
  </tag>
</taglib>

然后我们就可以在 JSP 文件中使用 Hello 标签了

webapp/custom_tag.jsp

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<meta charset="utf-8"/>
<title>JSP 自定义标签 | JSP 基础教程 | 简单教程(www.twle.cn)</title>
<p>一个简单的自定义标签</p>
<p><ex:Hello/></p>
<br/>
<p>JSP 自定义标签 | JSP 基础教程 | 简单教程(www.twle.cn)</p>
<br/>
<br/>

如果编译的时候提示 程序包javax.servlet.jsp.tagext不存在 可以通过 https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api 下载

在浏览器上输入 http://localhost:8080/jsp/custom_tag.jsp 显示结果如下

访问标签体

如果我们想让 <ex:Hello/> 像 JSP 标准标签库一样可以包含消息内容

<ex:Hello>Nice to see you, JSP</ex:Hello>

可以修改 HelloTag 类接收传递内容

package com.twle;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;

public class HelloTag extends SimpleTagSupport {

   StringWriter sw = new StringWriter();
   public void doTag()
      throws JspException, IOException
    {
       getJspBody().invoke(sw);
       getJspContext().getOut().println(sw.toString());
    }

}

然后再修改 customer.tld 文件

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD</short-name>
  <tag>
    <name>Hello</name>
    <tag-class>cn.twle.demo.HelloTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>
</taglib>

现在,<ex:Hello> 就会向我们想的那样工作了

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<meta charset="utf-8"/>
<title>JSP 自定义标签 | JSP 基础教程 | 简单教程(www.twle.cn)</title>
<p>一个简单的自定义标签</p>
<p><ex:Hello>Nice to see you,简单教程</ex:Hello></p>
<p>JSP 自定义标签 | JSP 基础教程 | 简单教程(www.twle.cn)</p>

在浏览器上输入 http://localhost:8080/jsp/custom_tag.jsp 显示结果如下

自定义标签属性

是不是还差点什么呢? 对,我们的 <ex:Hello> 不能设置属性

接下来我们做一些修改让 <ex:Hello> 可以设置各种属性

要接收属性,值自定义标签类必须实现 setter 方法

还是修改 HelloTag 类

// author: 简单教程(www.twle.cn)
// Copyright © 2015-2065 www.twle.cn. All rights reserved.

package cn.twle.demo;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;

public class HelloTag extends SimpleTagSupport
{
    private String message;

    public void setMessage(String msg)
    {
      this.message = msg;
    }

   StringWriter sw = new StringWriter();

   public void doTag() throws JspException, IOException 
   {
       if (message != null) 
       {
          /* 从属性中使用消息 */
          JspWriter out = getJspContext().getOut();
          out.println( message );
       } else {
          /* 从内容体中使用消息 */
          getJspBody().invoke(sw);
          getJspContext().getOut().println(sw.toString());
       }
   }
}

属性的名称是"message",所以 setter 方法​​是的 setMessage()

接在再修改下 custom.tld 文件使用 <attribute> 元素添加 "message" 属性

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD</short-name>
  <tag>
    <name>Hello</name>
    <tag-class>cn.twle.demo.HelloTag</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
       <name>message</name>
    </attribute>
  </tag>
</taglib>

好了,我们的 <ex:Hello> 可以设置属性了

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<meta charset="utf-8"/>
<title>JSP 自定义标签 | JSP 基础教程 | 简单教程(www.twle.cn)</title>
<p>一个简单的自定义标签</p>
<p><ex:Hello message="Hello 简单教程">Nice to see you,简单教程</ex:Hello></p>
<p>JSP 自定义标签 | JSP 基础教程 | 简单教程(www.twle.cn)</p>

我们的 <ex:Hello> 标签在既传入内容又传入属性的情况下会优先使用属性

在浏览器上输入 http://localhost:8080/jsp/custom_tag.jsp 显示结果如下

我们还可以给 custom.tld 文件还可以设置以下属性

属性 描述
name 定义属性的名称。每个标签的是属性名称必须是唯一的。
required 指定属性是否是必须的或者可选的,如果设置为false为可选。
rtexprvalue 声明在运行表达式时,标签属性是否有效。
type 定义该属性的Java类类型 。默认指定为String
description 描述信息
fragment 如果声明了该属性,属性值将被视为一个JspFragment。

以下是指定相关的属性实例:

.....
    <attribute>
      <name>attribute_name</name>
      <required>false</required>
      <type>java.util.Date</type>
      <fragment>false</fragment>
    </attribute>
.....

如果使用了两个属性,修改 TLD 文件

.....
    <attribute>
      <name>attribute_name1</name>
      <required>false</required>
      <type>java.util.Boolean</type>
      <fragment>false</fragment>
    </attribute>
    <attribute>
      <name>attribute_name2</name>
      <required>true</required>
      <type>java.util.Date</type>
    </attribute>
.....

JSP 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.