JSP - 自定义标签( Custom Tags)
在本章中,我们将讨论JSP中的自定义标记。 自定义标记是用户定义的JSP语言元素。 当包含自定义标记的JSP页面被转换为servlet时,标记将转换为对称为标记处理程序的对象的操作。 然后Web容器在执行JSP页面的servlet时调用这些操作。
JSP标记扩展允许您创建可以直接插入JavaServer Page的新标记。 JSP 2.0规范引入了用于编写这些自定义标记的简单标记处理程序。
要编写自定义标记,只需扩展SimpleTagSupport类并覆盖doTag()方法,您可以在其中放置代码以生成标记的内容。
创建“Hello”标签
考虑您要定义名为
<ex:Hello />
要创建自定义JSP标记,必须首先创建充当标记处理程序的Java类。 现在让我们创建HelloTag类,如下所示 -
package com.iowiki;
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-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.iowiki.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.iowiki;
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.iowiki.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.iowiki;
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.iowiki.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. | 财产和目的 |
---|---|
1 | name name元素定义属性的名称。 每个属性名称对于特定标记必须是唯一的。 |
2 | required 这指定此属性是必需的还是可选的。 对于可选项,这将是错误的。 |
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>
.....