views:

579

answers:

3

How would you properly render a list of objects in jsp with differing types? Say, for example, I have to render these different objects in a specified order.

One way could be to use a common type variable or instanceof but that means having a big switch/if statement to manage them all:

<c:forEach var="o" items="${bigListofObjects}"  >
    <c:choose>
        <c:when test='${o.type=="simple"}' >
        <!-- render simple -->
        </c:when>
        <c:when test='${o.type=="complex"}' >
        <!-- render complex -->
        </c:when>
        <!-- etc etc ... -->
    </c:choose>
</c:forEach>

I could add a render() method to each class but then that means mixing the view with the rest of the code.

What happens if I want to render another type later on? Is there something I could do with custom jsp tags?

+3  A: 

You could include another jsp that would do the correct rendering for a given type. for instance:

<c:forEach var="o" items="${bigListofObjects}"  >
    <c:import url="render-${o.type}.jsp"/>
</c:forEach>
Maurice Perry
A: 

You could have an outer forEach loop that iterates over a list of list of types:

<c:forEach var="t" items="${listOfTypes}">
    <c:forEach var="o" items="${bigListofObjects}">
        <if test='${o.type==t}'>
            <!-- render -->
        </c:if>
    </c:forEach>
</c:forEach>
karim79
+1  A: 

You could create an interface with a common method for each class to implement that emitted the HTML/JSP that you needed in a polymorphic way. I'm not that crazy about this suggestion because it leaks the user interface into the model classes in a bad way. Perhaps another way around it would be a Visitor pattern that could emit the UI for you.

Either way, you'd have to add code when a new type appeared.

I would be reluctant to create a custom tag library. You'd have to be careful to ensure that style didn't leak into it, making CSS skinning impossible.

duffymo