【问题标题】:How can I make this custom tag work as expected?如何使此自定义标签按预期工作?
【发布时间】:2014-09-27 06:56:09
【问题描述】:

这是我在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().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值再建表?

【问题讨论】:

    标签: java jsp tags taglib custom-tags


    【解决方案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>
    

    如果您想使用自定义标签,请尝试使用实现BodyTag 接口的BodyTagSupport

    示例代码:

    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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      输出的最可能原因是“k 值:1”不在 td 标记中。输出发生的情况是 table 标记内没有出现在 td 标记内的任何文本都被推送到表的开头,就像你的情况一样。查看生成的html源码,你会发现是真的。

      现在您找到了根本原因,所以我想您可以着手解决问题了……干杯

      这应该适合你

      不要从你的 jsp 中打印 k 的值

      <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>");
      }
      

      【讨论】:

        猜你喜欢
        • 2017-09-19
        • 1970-01-01
        • 2022-11-11
        • 2018-03-09
        • 2017-01-01
        • 2021-10-22
        • 2015-11-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多