Skip to Main Content

Java EE (Java Enterprise Edition) General Discussion

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

c:forEach and logic:iterate tags repeating elements of a collection

843840Feb 28 2008 — edited Feb 28 2008
I have an issue that makes absolutely no sense to me. Basically I am using struts, and I am returning a form that contains a List of customers. I am simply trying to iterate that list into a simple table for each customer. The end result will have rows for each table, but I tried to simplify this example.

The only filter is that I don't want to display customers that don't contain any data that I care to display. In my dataset, there is only one customer that has any data that I care about, and that has been verified in the database and in the backend action feeding the struts page.

I first attempted this with the c:forEach JSTL tag. What I saw was that the customers were just getting repeated. Instead of showing one table for each customer, it was repeating the tables for each customer equal to the size of the Collection. For example, there were *5* customers in the List, only customer C should have been set into a table, but the table for customer C was being repeated *5* times. I went into the backend code, and made sure the object being sent back to struts contained the correct number of records.

I then tried the same thing using the logic:iterate Struts EL tag. This did exactly the same thing. Instead of one table for customer C, I had 5 tables, all for customer C.

Frustrated, I then went back to just writing a basic scriptlet in the JSP, to iterate over the object returned from the struts action. When I did this, everything came back as normal. Only customer C met my conditional statement, and only customer C had a table created in the generated HTML.

Now I must be missing something with how the JSTL tags are handling the iteration, so I wanted to post the code to see if anyone had any idea what I am doing wrong here.

The JSP page is found below. As you can see, the first part is done as a scriptlet, and the last part is done with JSTL tags. Unless I am mistaken, the 2 approaches should produce the same result. Please let me know if I am missing something here.
<%@ include file="/common/customConfig.inc"%>
<%@ page import="java.util.Iterator,
    com.pw.cemp.webapp.common.forms.CempDocumentsForm,
    com.pw.cemp.webapp.common.views.CustomerView"%>


Write table with straight scriptlets...
<br />
<br />

<%
    CempDocumentsForm cdForm = 
        (CempDocumentsForm) session.getAttribute("cempDocsForm");
        
    Iterator itCustomers = cdForm.getCustomers().iterator();
    while (itCustomers.hasNext())
    {
        int idx = 0;
        CustomerView customer = (CustomerView) itCustomers.next();
        if (customer.getCemps() != null && !customer.getCemps().isEmpty())
        {
%>
        <table>
            <% if (idx == 0) { %>
                <caption>
                    Customer CEMP Listing
                </caption>                
            <% } %>
        
            <tbody>
                <tr>
                    <td class="level1">
                        <%=customer.getName() %> - 
                        <%=customer.getSapCustomerId() %>
                    </td>
                </tr>
            </tbody>
            
        </table>
<%       
        } 
        idx ++;
    }
%>

<br />
<br />
Now try using JSTL...
<br />
<br />

    <logic:iterate name="cempDocsForm" property="customers" id="customer" indexId="index">
    <!-- <c:forEach items="${cempDocsForm.customers}" var="customer" varStatus="status"> -->
            
        <c:if test="${not empty customer.cemps}">            
        <table>
            <c:if test="${index == 0}">
                <caption>
                    Customer CEMP Listing
                </caption>
            </c:if>
        
            <tbody>
                <tr>
                    <td class="level1">
                        <c:out value="${customer.name}" /> - 
                        <c:out value="${customer.sapCustomerId}" />
                    </td>
                </tr>
            </tbody>
            
        </table>
        </c:if>
        
    <!-- </c:forEach> -->
    </logic:iterate>
        
    <br />
    <br />
The code above produced the following HTML. As you can see, the scriptlet did exactly what I wanted, it produced 1 table for the only company that met the conditional statement. The JSTL section repeated the table for that one company, equal to the number of items in my List.
Write table with straight scriptlets...
<br />
<br />


        <table>
            
                <caption>
                    Customer CEMP Listing
                </caption>                            
        
            <tbody>
                <tr>
                    <td class="level1">
                        FMP Test Company - 
                        5
                    </td>
                </tr>
            </tbody>
            
        </table>

<br />
<br />
Now try using JSTL...
<br />
<br />
                    
        <table>            
                <caption>
                    Customer CEMP Listing
                </caption>            
        
            <tbody>
                <tr>
                    <td class="level1">
                        FMP Test Company - 
                        5
                    </td>
                </tr>
            </tbody>        
    
        </table>
        
        <table>

            <tbody>
                <tr>
                    <td class="level1">
                        FMP Test Company - 
                        5
                    </td>
                </tr>
            </tbody>
            
        </table>
        
        <table>            
        
            <tbody>
                <tr>
                    <td class="level1">
                        FMP Test Company - 
                        5
                    </td>
                </tr>
            </tbody>
            
        </table>
        
        <table>            
        
            <tbody>
                <tr>
                    <td class="level1">
                        FMP Test Company - 
                        5
                    </td>
                </tr>
            </tbody>
            
        </table>
                            
        <table>        
        
            <tbody>
                <tr>
                    <td class="level1">
                        FMP Test Company - 
                        5
                    </td>
                </tr>
            </tbody>
            
        </table>
        
    <br />
    <br />
Thanks in advance...

Edited by: cdbyrd on Feb 28, 2008 4:22 PM

Edited by: cdbyrd on Feb 28, 2008 5:12 PM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 27 2008
Added on Feb 28 2008
1 comment
1,502 views