在本章中,我们将讨论JSP中的自定义标记.自定义标记是用户定义的JSP语言元素.当包含自定义标记的JSP页面被转换为servlet时,标记将转换为对称为标记处理程序的对象的操作.然后Web容器在执行JSP页面的servlet时调用这些操作.
JSP标记扩展允许您创建可以直接插入JavaServer Page的新标记. JSP 2.0规范引入了用于编写这些自定义标记的简单标记处理程序.
要编写自定义标记,您只需扩展 SimpleTagSupport 类并覆盖 doTag()方法,您可以在其中放置代码以生成标记的内容.
考虑您要定义名为< ex:Hello>的自定义标记.并且你想以下列方式使用它而没有正文和负号;
<ex:Hello/>
要创建自定义JSP标记,必须首先创建一个充当标记处理程序的Java类.现在让我们创建 HelloTag 类如下 :
package com.it1352; 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()方法采用当前JspContext对象使用 getJspContext()方法并使用它将"Hello Custom Tag!"发送到当前的 JspWriter 对象
让我们编译上面的类并将其复制到环境变量CLASSPATH中可用的目录中.最后,创建以下标记库文件:< Tomcat-Installation-Directory> 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.IT屋.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> 的自定义标记,并且您希望以下列方式使用它与body :
<ex:Hello> This is message body </ex:Hello>
让我们在上面的标签代码中进行以下更改以处理标签的正文 :
package com.it1352; 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.IT屋.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.it1352; 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.IT屋.HelloTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>message</name> </attribute> </tag> </taglib>
让我们按照以下顺序跟踪带有消息属性的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
考虑包含属性的以下属性 :
S.No. | Property&目的 |
---|---|
1 | name name元素定义属性的名称.每个属性名称对于特定标记必须是唯一的. |
2 | required 这指定了此属性是必需的或是可选的.对于可选项,它将是错误的. |
3 | rtexprvalue 声明标签的运行时表达式值属性有效 |
4 | type 定义此属性的Java类类型.默认情况下,它假定为字符串 |
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> .....