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

1

Итак, это специальный тег, который у меня есть в файле jsp:

<myTags:myTag name="John">
    Value of k: ${valueOfK}
    <br />
</myTags:myTag>

И класс обработчика меток I:

@Override
public void doTag() throws JspException, IOException {
    getJspContext().getOut().print("<table>");
    for (int i = 0; i < 10; i++) {
        getJspContext().getOut().print("<tr>");
        for (int k = 0; k < i; k++) {
            getJspContext().getOut().print("<td>" + name + "</td>");
            getJspContext().setAttribute("valueOfK",k);
        }
        getJspBody().invoke(null);
        getJspContext().getOut().print("</tr>");
    }
    getJspContext().getOut().print("</table>");
}

Таким образом, выход будет:

Value of k: 
Value of k: 0
Value of k: 1
Value of k: 2
Value of k: 3
Value of k: 4
Value of k: 5
Value of k: 6
Value of k: 7
Value of k: 8
John
John    John
John    John    John
John    John    John    John
John    John    John    John    John
John    John    John    John    John    John
John    John    John    John    John    John    John
John    John    John    John    John    John    John    John
John    John    John    John    John    John    John    John    John

Но я хочу добиться чего-то вроде:

John Value of k: 1
John John Value of k: 2 

и т.д...

Почему все значения k сначала печатаются, а затем строятся таблицы?

Теги:
jsp
tags
taglib
custom-tags

2 ответа

1
Лучший ответ

Зачем вам нужен собственный тег, тогда как то же самое можно достичь с помощью встроенных тегов JSTL.

образец кода:

<table>
    <c:forEach begin="1" end="10" varStatus="status">
        <tr>
            <td>
                <c:forEach begin="1" end="${status.index}">
                    John&nbsp;
                </c:forEach>
                Value of k: ${status.index}
            </td>
        </tr>
    </c:forEach>
</table>

вывод:

John  Value of k: 1  
John  John  Value of k: 2  
John  John  John  Value of k: 3  
John  John  John  John  Value of k: 4  
John  John  John  John  John  Value of k: 5  
John  John  John  John  John  John  Value of k: 6  
John  John  John  John  John  John  John  Value of k: 7  
John  John  John  John  John  John  John  John  Value of k: 8  
John  John  John  John  John  John  John  John  John  Value of k: 9  
John  John  John  John  John  John  John  John  John  John  Value of k: 10  

Если вам нужно одно и то же в нескольких jsp, переместите код в отдельный JSP файл и просто включите его там, где это необходимо.

<jsp:include page="mytags.jsp">
    <jsp:param value="Koray" name="name" />
</jsp:include>

mytags.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<table>
    <c:forEach begin="1" end="10" varStatus="status">
        <tr>
            <td><c:forEach begin="1" end="${status.index}">
                        ${param.name}&nbsp;
                    </c:forEach> Value of k: ${status.index}</td>
        </tr>
    </c:forEach>
</table>

Если вы хотите использовать пользовательский тег, попробуйте с помощью BodyTagSupport который реализует интерфейс BodyTag.

Изображение 174551

образец кода:

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class MyTag extends BodyTagSupport {

    private String name;
    private int counter;

    public int doStartTag() throws JspException {
        counter = 1;
        JspWriter out = pageContext.getOut();
        try {
            out.print(name);
            pageContext.setAttribute("valueOfK", counter);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return EVAL_BODY_INCLUDE;
    }

    public int doAfterBody() {
        counter++;
        if (counter == 10) {
            return SKIP_BODY;
        } else {
            JspWriter out = pageContext.getOut();
            try {
                StringBuilder names = new StringBuilder();
                for (int k = 0; k < counter; k++) {
                    names.append(name).append(" ");
                }
                out.print(names.toString());
                pageContext.setAttribute("valueOfK", counter);
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return EVAL_BODY_AGAIN;
        }
    }

    public int doEndTag() throws JspException {
        return EVAL_PAGE;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
1

Наиболее вероятной причиной для вывода является то, что "Значение k: 1" не находится в теге td. Что происходит с выходом, так это то, что любой текст внутри тега таблицы, который не входит в тег td, помещается в начало таблицы, как в вашем случае. Посмотрите на сгенерированный источник html, и вы обнаружите, что это правда.

Теперь у вас есть первопричина, поэтому я полагаю, что вы можете работать над решением... Cheers

Вот что должно сработать для вас

dont print Значение k: из вашего jsp

<myTags:myTag name="John">
    <%--Value of k: ${valueOfK}
    <br />--%>
</myTags:myTag>

вместо этого поместите его в свой класс тегов

@Override
public void doTag() throws JspException, IOException {
    getJspContext().getOut().print("<table>");
    for (int i = 0; i < 10; i++) {
        getJspContext().getOut().print("<tr>");
        for (int k = 0; k < i; k++) {
            getJspContext().getOut().print("<td>" + name + "</td>");
            getJspContext().getOut().print("<td>Value of k: " + (k + 1) + "</td>");
            getJspContext().setAttribute("valueOfK",k);
        }
        getJspBody().invoke(null);
        getJspContext().getOut().print("</tr>");
    }
    getJspContext().getOut().print("</table>");
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню