38

I want to loop through an ArrayList of "Festivals" and get their information with get methods, printing out all its values. For some reason when I use this code, it will always choose the "0"th value and not increment the loop.

If I hard code the values as "get(1)" it will get the correct values so my issue is clearly with the syntax.

<h1>All Festival Information</h1>
    <jsp:useBean id="allFestivals" type="java.util.ArrayList" scope="session" />
    <table border="1">
        <tr>
            <td>Festival Name:</td>
            <td>Location:</td>
            <td>Start Date:</td>
            <td>End Date:</td>
            <td>URL:</td>
        </tr>
        <% for(int i = 0; i < allFestivals.size(); i+=1) { %>
            <tr>      
                <td>${allFestivals.get(i).getFestivalName()}</td>
                <td>${allFestivals.get(i).getLocation()}</td>
                <td>${allFestivals.get(i).getStartDate()}</td>
                <td>${allFestivals.get(i).getEndDate()}</td>
                <td>${allFestivals.get(i).getURL()}</td>  
            </tr>
        <% } %>
    </table> 
edwoollard
  • 12,245
  • 6
  • 43
  • 74
Jack Dalton
  • 3,536
  • 5
  • 23
  • 40
  • 1
    Writing Java code inside JSP page is not recommended. Use JSTL core tag `` instead. – Eng.Fouad Apr 05 '13 at 16:54
  • Just stop using `<% %>`. You'll automatically be forced to do the right things. See also http://stackoverflow.com/questions/3177733/how-to-avoid-java-code-in-jsp-files/3180202#3180202 – BalusC Apr 05 '13 at 16:59

2 Answers2

80

You concrete problem is caused because you're mixing discouraged and old school scriptlets <% %> with its successor EL ${}. They do not share the same variable scope. The allFestivals is not available in scriptlet scope and the i is not available in EL scope.

You should install JSTL (<-- click the link for instructions) and declare it in top of JSP as follows:

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

and then iterate over the list as follows:

<c:forEach items="${allFestivals}" var="festival">
    <tr>      
        <td>${festival.festivalName}</td>
        <td>${festival.location}</td>
        <td>${festival.startDate}</td>
        <td>${festival.endDate}</td>
        <td>${festival.URL}</td>  
    </tr>
</c:forEach>

(beware of possible XSS attack holes, use <c:out> accordingly)

Don't forget to remove the <jsp:useBean> as it has no utter value here when you're using a servlet as model-and-view controller. It would only lead to confusion. See also our servlets wiki page. Further you would do yourself a favour to disable scriptlets by the following entry in web.xml so that you won't accidently use them:

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <scripting-invalid>true</scripting-invalid>
    </jsp-property-group>
</jsp-config>
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Worked perfectly. Not sure why I was told to use the "<% %>" as most information on-line conforms to your method using " – Jack Dalton Apr 05 '13 at 17:26
  • You're welcome. Perhaps you were relying on a resource which is more than a decade old. – BalusC Apr 05 '13 at 17:27
  • if you want to get the index of the list like me, here it is: http://stackoverflow.com/a/18826043/926460 – Timeless Mar 11 '15 at 02:07
  • "My university. Talk about a bit old school teaching" -- I'm taking a class on this now. It's 2016 and we're being taught techniques that were bad practice over a decade ago. It's amazing what lingers on with some profs ... – A B May 06 '16 at 13:44
22

Do this

    <% for(int i = 0; i < allFestivals.size(); i+=1) { %>
        <tr>      
            <td><%=allFestivals.get(i).getFestivalName()%></td>
        </tr>
    <% } %>

Better way is to use c:foreach see link jstl for each

Sajan Chandran
  • 11,287
  • 3
  • 29
  • 38