JSTL while loop (without scriptlets)

坚强是说给别人听的谎言 提交于 2019-12-23 01:52:07

问题


Is there a way to create a while loop like structure with JSP, without using a scriptlet?

I ask as I have a linked list-like structure (specifically, printing the cause chain for exceptions) which AFAIK does not have an iterator interface to use forEach on.


回答1:


You could do it by iterating over a list

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

EDIT:

You could have a method like the following to transform an exception and its causes into list that later could be shown using a 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;
}

For example:

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



回答2:


The controller, whose role is to prepare the data for the view, should transform this non-iterable data structure into a collection that can be used by the <c:forEach> JSTL tag.




回答3:


What I ended up doing was a static loop with an arbitrary upper bound:

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

This is really only useful only if you have some prior knowledge of the number of iterations, don't mind not displaying all information, or don't mind a potentially significant performance hit.

Keep in mind there is no early exit condition, so putting 2,147,483,647 as an upper bound would be a decidedly bad idea.

And for the curious, solution for outputting exceptions (sans formatting):

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



回答4:


In case you don't want to iterate over Collections, you can use <c:forEach> as a conventional loop equivalent by the following approach:

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

This will produce a select drop down ranging from 0 to 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>


来源:https://stackoverflow.com/questions/17702459/jstl-while-loop-without-scriptlets

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!