jstl foreach omit an element in last record

trying to use this jstl to formulate a json string, how can i make the segment not to put a comma in the end of the last record? note the comma in the end

<c:forEach items="${fileList}" var="current">
    { id:1001,data:["<c:out value="${current.fileName}" />" , "<c:out value="${current.path}" />" , "<c:out value="${current.size}" />" , "<c:out value="${current.type}" />"] },
</c:forEach>

Solution 1:

Just use LoopTagStatus#isLast().

<c:forEach items="${fileList}" var="current" varStatus="loop">
    { id: 1001,
      data: [
        "<c:out value="${current.fileName}" />",
        "<c:out value="${current.path}" />",
        "<c:out value="${current.size}" />",
        "<c:out value="${current.type}" />"
      ]
    }<c:if test="${!loop.last}">,</c:if>
</c:forEach>

You can also use the conditional operator in EL instead of <c:if>:

    ${!loop.last ? ',' : ''}

Solution 2:

One thing I never liked about JSTL (actually I think is the only thing :)) is the fact that there is no way to retrieve the size of a list/collection.

EDIT: ok, so it was possible but I didn't know it :( see here.

The forEach tag has the varStatus attribute which you can use to determine the index of the row (index/count properties on the varStatus variable) but you have to test if you are at the last position in the list, that means having the list size beforehand:

<c:forEach items="${fileList}" var="current" varStatus="status">
   ...
  <c:if test="${not (status.count eq listSize)}">,</c:if>
</c:forEach>

But you will have to place the listSize in scope, manually, before doing this sort of thing.

What I did in one of my projects was to create myself a tag that takes a collection and returns the value:

  <myLib:collectionSize collection="${fileList}" var="listSize" />
  <c:forEach items="${fileList}" var="current" varStatus="status">
     ...
    <c:if test="${not (status.count eq listSize)}">,</c:if>
  </c:forEach>

You could do the same if you have this sort of code often (else you can just add it in scope with whatever is convenient to you).

Solution 3:

by Check a collection size with JSTL the answer were to use the functions tag

put this at the top of the page to allow the fn namespace

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

and use like this in your jsp page

<p>The length of the companies collection is : ${fn:length(companies)}</p>