68

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>
Doug Porter
  • 7,721
  • 4
  • 40
  • 55
nokheat
  • 1,167
  • 4
  • 14
  • 23

3 Answers3

171

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 ? ',' : ''}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    +1. A much better solution than mine. @nokheat: you should mark this as the accepted answer. –  Jun 23 '10 at 13:01
3

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

Community
  • 1
  • 1
  • After a quick search I found this: http://stackoverflow.com/questions/851880/check-a-collection-size-with-jstl. Maybe it can help you even more. –  Jun 23 '10 at 06:29
  • since the list object has a size() function, can i use list.size to make it look more elegrant? – nokheat Jun 23 '10 at 06:31
  • JSTL mainly goes for accessor fields "getProp" and "setProp" and in your JSP you will go for "prop". You could do "list.size" if the list had a method called "getSize" but id doesn't, it just has "size". –  Jun 23 '10 at 06:37
  • @nokheat: BalusC provided a more cleaner solution to your post. Go for his response. –  Jun 23 '10 at 13:02
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>
Community
  • 1
  • 1
nokheat
  • 1,167
  • 4
  • 14
  • 23