2.8.6 以页面片段作为属性的标签

2.8.6 以页面片段作为属性的标签

JSP2规范的自定义标签还允许直接将一段“页面片段”作为属性,这种方式给自定义标签提供了更大的灵活性.
以“页面片段”为属性的标签与普通标签区别并不大,只有两个简单的改变。

  1. 标签处理类中定义类型为JspFragment的属性,该属性代表了“页面片段”。
  2. 使用标签库时,通过<jsp:attribute>动作指令为标签的属性指定值

下面的程序定义了一个标签处理类,该标签处理类中定义了一个JspFragment类型的属性,即表明该标签允许使用“页面片段”类型的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package lee;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;

public class FragmentTag extends SimpleTagSupport {
private JspFragment fragment;

// fragment的setter和getter方法
public void setFragment(JspFragment fragment) {
this.fragment = fragment;
}

public JspFragment getFragment() {
return this.fragment;
}

@Override
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println("<div style='padding:10px;border:1px solid black;" + ";border-radius:20px'>");
out.println("<h3>下面是动态传入的JSP片段</h3>");
// 调用、输出“页面片段”
fragment.invoke(null);
out.println("</div");
}
}

上面的程序中定义了fragment成员变量,该成员变量代表了使用该标签时的“页面片段”,配置该标签与配置普通标签并无任何区别,增加如下配置片段即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<tag>
<!-- 定义标签名 -->
<name>fragment</name>
<!-- 定义标签处理类 -->
<tag-class>lee.FragmentTag</tag-class>
<!-- 指定该标签不支持标签体 -->
<body-content>empty</body-content>
<!-- 定义标签属性:fragment -->
<attribute>
<name>fragment</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
</tag>

从上面标签库的配置片段来看,这个自定义标签并没有任何特别之处,就是一个普通的带属性标签,该标签的标签体为空.
由于该标签需要一个fragment属性,该属性的类型为JspFragment,因此使用该标签时需要使用<jsp:attribute>动作指令来设置属性值,如以下代码片段所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!-- 导入标签库,指定mytag前缀的标签,
由http://www.crazyit.org/mytaglib的标签库处理 -->
<%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>
<!DOCTYPE html>
<html>
<head>
<title>自定义标签示范</title>
</head>
<body bgcolor="#ffffc0">
<h2>下面显示的是自定义标签中的内容</h2>
<mytag:fragment>
<jsp:attribute name="fragment">
<%-- 使用jsp:attribute标签传入fragment参数(该注释不能放在fragment内) %-->
<%-- 下面是动态的JSP页面片段 --%>
<mytag:helloWorld/>
</jsp:attribute>
</mytag:fragment>
<br/>
<mytag:fragment>
<jsp:attribute name="fragment">
<%-- 下面是动态的JSP页面片段 --%>
${pageContext.request.remoteAddr}
</jsp:attribute>
</mytag:fragment>
</body>
</html>

由于程序指定了fragment标签的标签体为empty,因此程序中fragment开始标签和fragment结束标签之间只能使用jsp:attribute子元素,不允许出现其他内容,甚至连注释都不允许.

测试

上面的代码片段中的jsp:attribute标签用于为标签的fragment属性赋值,
第一个例子使用了另一个简单标签来生成页面片段;
第二个例子使用了JSP2EL来生成页面片段;在浏览器中浏览该页面,将看到如图2.37所示的效果。