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