JSP - 自定义标签



本章将讨论 JSP 中的自定义标签。自定义标签是用户定义的 JSP 语言元素。当包含自定义标签的 JSP 页面被转换为 Servlet 时,该标签将被转换为对称为标签处理器的对象的运算。然后,当执行 JSP 页面的 Servlet 时,Web 容器将调用这些运算。

JSP 标签扩展允许您创建新的标签,您可以直接将其插入到 JavaServer 页面中。JSP 2.0 规范引入了简单的标签处理器来编写这些自定义标签。

要编写自定义标签,您可以简单地扩展SimpleTagSupport类并覆盖doTag()方法,您可以在其中放置代码以生成标签的内容。

创建“Hello”标签

假设您想定义一个名为<ex:Hello>的自定义标签,并且您想按照以下方式在没有主体的情况下使用它:

<ex:Hello />

要创建自定义 JSP 标签,您必须首先创建一个充当标签处理器的 Java 类。现在让我们创建如下HelloTag类:

package com.tutorialspoint;

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!");
   }
}

上面的代码很简单,其中doTag()方法使用getJspContext()方法获取当前的 JspContext 对象,并使用它将“Hello Custom Tag!”发送到当前的JspWriter对象。

让我们编译上面的类并将其复制到环境变量 CLASSPATH 中可用的目录中。最后,创建以下标签库文件:<Tomcat-安装目录>webapps\ROOT\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>com.tutorialspoint.HelloTag</tag-class>
      <body-content>empty</body-content>
   </tag>
</taglib>

现在让我们在我们的 JSP 程序中使用上面定义的自定义标签Hello,如下所示:

<%@ taglib prefix = "ex" uri = "WEB-INF/custom.tld"%>

<html>
   <head>
      <title>A sample custom tag</title>
   </head>
   
   <body>
      <ex:Hello/>
   </body>
</html>

调用上面的 JSP,这应该会产生以下结果:

Hello Custom Tag!

访问标签体

您可以像使用标准标签一样在标签体中包含消息。假设您想定义一个名为<ex:Hello>的自定义标签,并且您想按照以下方式在有主体的情况下使用它:

<ex:Hello>
   This is message body
</ex:Hello>

让我们对上面的标签代码进行以下更改以处理标签体:

package com.tutorialspoint;

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());
   }
}

在这里,调用产生的输出首先被捕获到StringWriter中,然后再写入与标签关联的 JspWriter。我们需要更改 TLD 文件,如下所示:

<taglib>
   <tlib-version>1.0</tlib-version>
   <jsp-version>2.0</jsp-version>
   <short-name>Example TLD with Body</short-name>
   
   <tag>
      <name>Hello</name>
      <tag-class>com.tutorialspoint.HelloTag</tag-class>
      <body-content>scriptless</body-content>
   </tag>
</taglib>

现在让我们使用正确的正文调用上面的标签,如下所示:

<%@ taglib prefix = "ex" uri = "WEB-INF/custom.tld"%>

<html>
   <head>
      <title>A sample custom tag</title>
   </head>
   
   <body>
      <ex:Hello>
         This is message body
      </ex:Hello>
   </body>
</html>

您将收到以下结果:

This is message body

自定义标签属性

您可以与自定义标签一起使用各种属性。为了接受属性值,自定义标签类需要实现setter方法,与 JavaBean setter 方法相同,如下所示:

package com.tutorialspoint;

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) {
         /* Use message from attribute */
         JspWriter out = getJspContext().getOut();
         out.println( message );
      } else {
         /* use message from the body */
         getJspBody().invoke(sw);
         getJspContext().getOut().println(sw.toString());
      }
   }
}

属性的名称是“message”,因此 setter 方法是setMessage()。现在让我们使用<attribute>元素在 TLD 文件中添加此属性,如下所示:

<taglib>
   <tlib-version>1.0</tlib-version>
   <jsp-version>2.0</jsp-version>
   <short-name>Example TLD with Body</short-name>
   
   <tag>
      <name>Hello</name>
      <tag-class>com.tutorialspoint.HelloTag</tag-class>
      <body-content>scriptless</body-content>
      
      <attribute>
         <name>message</name>
      </attribute>
   
   </tag>
</taglib>

让我们按照带有 message 属性的 JSP 如下所示:

<%@ taglib prefix = "ex" uri = "WEB-INF/custom.tld"%>

<html>
   <head>
      <title>A sample custom tag</title>
   </head>
   
   <body>
      <ex:Hello message = "This is custom tag" />
   </body>
</html>

这将产生以下结果:

This is custom tag

考虑为属性包含以下属性:

序号 属性及用途
1

name

name 元素定义属性的名称。每个属性名称对于特定标签必须唯一。

2

required

这指定此属性是必需的还是可选的。对于可选属性,它将为 false。

3

rtexprvalue

声明标签属性的运行时表达式值是否有效。

4

type

定义此属性的 Java 类类型。默认情况下,它假定为String

5

description

可以提供信息性描述。

6

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>
.....
广告