Как создать обработчик тега итерации, который определяет переменную - PullRequest
0 голосов
/ 23 января 2019

Проблема

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

1 Ответ

0 голосов
/ 23 января 2019

Таким образом, в конечном итоге это было изменение одного слова.

В моем TLD я определяю body-content тега как tagdependent.Я должен был изменить это на scriptless.Судя по всему, повторное изучение документов никому не повредит ...

...