Как я могу создать собственный JSP-тег, который использует другие теги JSP?

Я хотел бы написать настраиваемый тег JSP, выход которого включает в себя другие теги JSP, которые также должны быть динамически оценены. Но, очевидно, все, что мой подкласс TagSupport пишет в pageContext.getOut(), просто переходит прямо к клиенту без какой-либо дополнительной оценки.

У меня такое чувство, что это должно быть очень просто, так как это похоже на одну из первых вещей, которые хотелось бы использовать в пользовательских тегах для: инкапсуляции и повторного использования других настраиваемых тегов, избегая дублирования кода.

Как сделать следующий код, как он хочет сделать?:

public class MyTag extends TagSupport {
    public int doStartTag() throws JspException {
        try {
            pageContext.getOut().println(
              "The output from this tag includes other tags " +
              "like <mypackage:myOtherTag>this one</mypackage:myOtherTag> " +
              "which should themselves be evaluated and rendered."
            )
        } catch (IOException e) {
            throw new JspException(e);
        }
        return SKIP_BODY;
    }   
}

Изменить: некоторый фон в моем конкретном случае использования, если он помогает. У меня есть настраиваемый тег <user>, который динамически отображает имя пользователя таким образом, который полезен для моего приложения (мышь-зависание для имени, фамилии, номера телефона и т.д.). Теперь я пишу еще один тег <comment> для отображения комментариев пользователей, и я хотел бы использовать существующий тег <user> для рендеринга имен пользователей на выходе тега <comment>.

Ответ 1

Вы можете разделить классы на класс тегов и класс tagRenderer.

В вашей ситуации будут два новых класса, называемые CommentTagRenderer и UserTagRenderer.

Вот пример нового CommentTag

public int doStartTag() throws JspException {
    JspWriter out = pageContext.getOut(); 
    Comment comment = getComment();
    User user =  getUser();

    CommentTagRenderer commentRenderer = new CommentTagRenderer(out);
    UserTagRenderer userRenderer = new UserTagRenderer(out);

    try {
        commentRenderer.renderComment(comment);
        userRenderer.renderUser(user);          
    } catch (IOException e) {
        //some error handling
    }
    return SKIP_BODY;
  }

И вот пример CommentTagRenderer

private Writer out;
public CommentTagRenderer(Writer out) {
    this.out = out;
}

public void renderComment(Comment comment) throws IOException {
    out.write("<div>");
    out.write(comment.getComment());
    out.write("</div>");
}

Ответ 2

Самый простой способ - написать свой тег custome как файл тега JSP, а не на Java. Таким образом, новый тег может легко использовать другие пользовательские теги. Создайте файл myTag.tag в /WEB -INF/tags и используйте следующий код:

<%@ tag %>
<%@ attribute name="value" required="true" rtexprvalue="true" type="java.lang.String"%>
<%@ taglib prefix="mypackage" uri="mypackage.tld" %>
The output from this tag includes other tags 
like <mypackage:myOtherTag>${value}</mypackage:myOtherTag>
which should themselves be evaluated and rendered.

Подробнее о файлах тегов здесь: http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPTags5.html