【问题标题】:JSTL while loop (without scriptlets)JSTL while 循环(无脚本)
【发布时间】:2013-07-17 14:25:41
【问题描述】:

有没有办法在不使用 scriptlet 的情况下使用 JSP 创建类似 while 循环的结构?

我问,因为我有一个类似链表的结构(特别是打印异常的原因链),AFAIK 没有用于 forEach 的迭代器接口。

【问题讨论】:

  • 让控制器把这个结构转换成一个Iterable结构,在JSP中使用forEach。这就是控制器的作用:为视图准备数据。
  • @JBNizet 那就是答案。给它,如果我没有其他人,我会接受。

标签: jsp jstl


【解决方案1】:

我最终做的是一个带有任意上限的静态循环:

<c:forEach begin="0" end="${<upper_bound>}" varStatus="loop">
    <c:if test="${!<exit_condition>}">
        <!-- loop output here -->
    </c:if>
    <c:if test="${loop.last && !<exit_condition>}">
        <!-- overflow output here -->
    </c:if>
</c:forEach>

仅当您事先了解迭代次数、不介意不显示所有信息或不介意潜在的显着性能影响时,这才真正有用。

请记住,没有提前退出条件,因此将 2,147,483,647 作为上限绝对是个坏主意。

对于输出异常(无格式)的好奇解决方案:

<c:forEach begin="0" end="10" varStatus="loop">
    <c:if test="${!loop.first}">
        Caused By:
    </c:if>
    <c:if test="${throwable != null}">
        Message: ${throwable.message} <br/>
        <c:forEach items="${throwable.stackTrace}" var="trace">
            ${trace} <br/>
        </c:forEach>
    </c:if>
    <c:if test="${loop.last && throwable != null}">
        More causes not listed...
    </c:if>
    <c:set var="throwable" value="${throwable.cause}" />
</c:forEach>

【讨论】:

    【解决方案2】:

    你可以通过遍历一个列表来做到这一点

    <c:forEach var="entry" items="${requestScope['myErrorList']}">
    ${entry.message}<br/>
    </c:forEach>
    

    编辑:

    您可以使用如下方法将异常及其原因转换为稍后可以使用 forEach

    显示的列表
    public static List<Throwable> getExceptionList(Exception ex) {
      List<Throwable> causeList = new ArrayList<Throwable>();
      causeList.add(ex);
      Throwable cause = null;
      while ((cause = ex.getCause()) != null && !causeList.contains(cause)) {
        causeList.add(cause);
      }
      return causeList;
    }
    

    例如:

    try {
      ...
    } catch (... ex) {
      request.setAttribute("myErrorList", getExceptionList(ex));
    }
    

    【讨论】:

    • 当有问题的对象没有实现 Collection 接口时,我不确定这如何解决问题。能详细点吗?
    • 这是一个“限制”,您要使用 forEach。但是您可以简单地将自己的列表包装到 servlet 内的任何类型的集合中。您应该在将响应发送到页面之前执行此操作。请详细说明您要迭代到的对象之王
    • 在问题中:“异常的原因链”。 throwable.getCause() 获取前一个原因。我需要能够遍历所有原因。
    【解决方案3】:

    控制器,其作用是为视图准备数据,应该将这个不可迭代的数据结构转换成一个可以被&lt;c:forEach&gt;JSTL标签使用的集合。

    【讨论】:

    • 在问题中:“没有用于 forEach 的迭代器接口”。
    • 哦,对不起,我错过了。使控制器将结构转换为可迭代的结构。
    【解决方案4】:

    如果您不想遍历集合,可以通过以下方法将&lt;c:forEach&gt; 用作常规循环等效项:

    <c:set var="startIndex" scope="page" value="0"/>
    <c:set var="endIndex" scope="page" value="12"/>
    
    <select name="milestone_count" id="milestone_count">
        <option value="">-select-</option>
        <c:forEach begin="${startIndex}" end="${endIndex}" step="1" var="index">
            <option value="${index}">${index}</option>
        </c:forEach>
    </select>
    

    这将产生一个从 0 到 12 的选择下拉列表

    【讨论】:

      【解决方案5】:

      http://www.tutorialspoint.com/jsp/jstl_core_foreach_tag.htm

      <c:forEach var="item" items="${myList}">
         ${item}"
      </c:forEach>
      
      <c:forEach var="entry" items="${myMap}">
        Key: <c:out value="${entry.key}"/>
        Value: <c:out value="${entry.value}"/>
      </c:forEach>
      

      【讨论】:

      • 在问题中:“没有用于 forEach 的迭代器接口”
      • Isee,然后制作一个,就像@JB Nizet 说的那样:)
      猜你喜欢
      • 2018-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      • 2015-04-27
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多