Проблема
Я пытаюсь создать собственный обработчик тега, цель которого состоит в том, чтобы перебрать указанный список и объединить элементы с указанным разделителем. Подпись тега: <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
, и в методе 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}