JSP 自定义标签

  • 自定义标签

    在本章中,我们将讨论JSP中的自定义标签。自定义标签是用户定义的JSP语言元素。当将包含自定义标签的JSP页面转换为servlet时,该标记将转换为对称为标记处理程序的对象的操作。然后,当执行JSP页面的servlet时,Web容器将调用这些操作。JSP标记扩展允许您创建可以直接插入JavaServer Page中的新标记。JSP 2.0规范引入了用于编写这些自定义标签的简单标签处理程序。要编写自定义标签,只需扩展SimpleTagSupport类并覆盖doTag()方法,即可在其中放置代码以生成标签内容。
  • 创建“Hello”标签

    考虑您要定义一个名为<ex:Hello>的自定义标签,并且您想以以下方式使用它而不使用主体-
    
    <ex:Hello />
    
    要创建自定义JSP标记,必须首先创建一个充当标记处理程序的Java类。现在让我们如下创建HelloTag类:
    
    package com.jc2182.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!");
       }
    }
    
    上面的代码具有简单的编码,其中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.jc2182.demo.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.jc2182.demo;
    
    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>
    
    现在让我们用适当的body来调用上面的标签,如下所示:
    
    <%@ 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.jc2182.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) {
             /* 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.jc2182.demo.HelloTag</tag-class>
          <body-content>scriptless</body-content>
          
          <attribute>
             <name>message</name>
          </attribute>
       
       </tag>
    </taglib>
    
    让我们测试JSP的message属性,如下所示:
    
    <%@ 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>
    
    运行JSP ,将产生如下效果:
    
    This is custom tag
    
    自定义标签建议包括以下属性-
    属性 目的
    name name元素定义属性的名称。 每个属性名称对于特定标签必须唯一。
    required 这指定此属性是必需属性还是可选属性。 对于可选将是错误的。
    rtexprvalue 声明标签属性的运行时表达式值是否有效
    type 定义此属性的Java类类型。 默认情况下,它假定为字符串
    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>
    .....