如何创建定义变量的迭代标记处理程序
How to create an iteration tag handler that define a variable
问题
我正在尝试创建一个自定义标记处理程序,其目的是循环遍历给定的列表并将项目与给定的分隔符连接起来。标签的签名是:<custom:joinList list="${product.vendors}" delimiter=", " var="vendor">
。一些笔记。 list
属性应该是一个 Collection.class
对象。 delimiter
始终是 String
,var
是正文在每个循环中可以访问的变量。所以标签应该总是有一个主体来打印每个项目,然后标签处理程序会在末尾附加 delimiter
。
例如,这就是如何从 JSP:
调用标签
<custom:joinList list="${product.vendors}" delimiter=", " var="vendor">
${vendor.id} // Vendor obviously has a getId() method
</custom:joinList>
我试过的
首先,我创建了一个扩展 javax.servlet.jsp.tagext.SimpleTagSupport
的 class,在 doTag()
方法中,我将列表中的下一项作为 pageContext
中的属性传递。
其次,我尝试扩展 javax.servlet.jsp.tagext.TagSupport
,但后来我不知道如何在每次主体执行后写入 out
编写器。
代码示例
定义标签的 TLD:
<tag>
<description>Joins a Collection with the given delimiter param</description>
<name>joinList</name>
<tag-class>com.myproject.tags.JoinListTag</tag-class>
<body-content>tagdependent</body-content>
<attribute>
<description>The collection to be printed</description>
<name>list</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>The delimiter that is going to be used</description>
<name>delimiter</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>The item that will return on each loop to get a handle on each iteration</description>
<name>var</name>
<required>true</required>
</attribute>
</tag>
这是自定义标签处理程序,我想它非常简单。
public class JoinListTag extends SimpleTagSupport {
private Iterator iterator;
private String delimiter;
private String var;
public void setList(Collection list) {
if (list.size() > 0) {
this.iterator = list.iterator();
}
}
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
public void setVar(String var) {
this.var = var;
}
@Override
public void doTag() throws JspException, IOException {
if (iterator == null) {
return;
}
while (iterator.hasNext()) {
getJspContext().setAttribute(var, iterator.next()); // define the variable to the body
getJspBody().invoke(null); // invoke the body
if (iterator.hasNext()) {
getJspContext().getOut().print(delimiter); // apply the delimiter
}
}
}
}
从上面我期望打印 1, 2, 3
如果 product.vendors
列表是这样填充的,但是我得到 ${vendor.id}, ${vendor.id}, ${vendor.id}
所以最终是一个词的变化。
在我的 TLD 中,我将标签的 body-content
定义为 tagdependent
。我不得不将其更改为 scriptless
。显然再次浏览文档不会伤害任何人...
问题
我正在尝试创建一个自定义标记处理程序,其目的是循环遍历给定的列表并将项目与给定的分隔符连接起来。标签的签名是:<custom:joinList list="${product.vendors}" delimiter=", " var="vendor">
。一些笔记。 list
属性应该是一个 Collection.class
对象。 delimiter
始终是 String
,var
是正文在每个循环中可以访问的变量。所以标签应该总是有一个主体来打印每个项目,然后标签处理程序会在末尾附加 delimiter
。
例如,这就是如何从 JSP:
调用标签<custom:joinList list="${product.vendors}" delimiter=", " var="vendor">
${vendor.id} // Vendor obviously has a getId() method
</custom:joinList>
我试过的
首先,我创建了一个扩展 javax.servlet.jsp.tagext.SimpleTagSupport
的 class,在 doTag()
方法中,我将列表中的下一项作为 pageContext
中的属性传递。
其次,我尝试扩展 javax.servlet.jsp.tagext.TagSupport
,但后来我不知道如何在每次主体执行后写入 out
编写器。
代码示例
定义标签的 TLD:
<tag>
<description>Joins a Collection with the given delimiter param</description>
<name>joinList</name>
<tag-class>com.myproject.tags.JoinListTag</tag-class>
<body-content>tagdependent</body-content>
<attribute>
<description>The collection to be printed</description>
<name>list</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>The delimiter that is going to be used</description>
<name>delimiter</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>The item that will return on each loop to get a handle on each iteration</description>
<name>var</name>
<required>true</required>
</attribute>
</tag>
这是自定义标签处理程序,我想它非常简单。
public class JoinListTag extends SimpleTagSupport {
private Iterator iterator;
private String delimiter;
private String var;
public void setList(Collection list) {
if (list.size() > 0) {
this.iterator = list.iterator();
}
}
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
public void setVar(String var) {
this.var = var;
}
@Override
public void doTag() throws JspException, IOException {
if (iterator == null) {
return;
}
while (iterator.hasNext()) {
getJspContext().setAttribute(var, iterator.next()); // define the variable to the body
getJspBody().invoke(null); // invoke the body
if (iterator.hasNext()) {
getJspContext().getOut().print(delimiter); // apply the delimiter
}
}
}
}
从上面我期望打印 1, 2, 3
如果 product.vendors
列表是这样填充的,但是我得到 ${vendor.id}, ${vendor.id}, ${vendor.id}
所以最终是一个词的变化。
在我的 TLD 中,我将标签的 body-content
定义为 tagdependent
。我不得不将其更改为 scriptless
。显然再次浏览文档不会伤害任何人...