Search code examples
jspjstljsp-tagscustom-tag

JSP/JSTL: Passing a Collection to a Custom Tag


I'm trying to implement a custom JSP tag that accepts as an attribute a Collection of objects and outputs them as a JSON-formatted array (each object in the Collection provides a getJsonString() method that returns a JSON-formatted representation of that object). I have my tag implemented as such:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ attribute name="objects" required="true" rtexprvalue="true" %>
<c:set var="output" value="" />
<c:forEach var="obj" items="${objects}">
    <c:if test="${! empty showComma}">
        <c:set var="output" value="${output}, " /> 
    </c:if>
    <c:set var="output" value="${output}${obj.jsonString}" />
    <c:set var="showComma" value="yes" />
</c:forEach>
[${output}]

...and I want to be able to use it by doing something like:

<myTaglib:jsonArray objects="${myCollection}" />

When I try to use the tag, however, I get a stack trace saying:

javax.el.PropertyNotFoundException: Property 'jsonString' not found on type java.lang.String

So it's complaining about the ${obj.jsonString} expression, but I'm definitely not passing a Collection of strings. Moreover, if I change it to ${obj} I see the correct object types being output, and if I copy/paste the code for my custom tag into the JSP where I want to use it, it works correctly, so I'm really not sure what's going on here.

I assume there is some problem with how I'm passing the Collection into the custom tag, but I can't work out what it is. Any ideas?


Solution

  • I found the solution, I needed to add type="java.util.Collection" to the attribute declaration, as in:

    <%@ attribute name="objects" required="true" rtexprvalue="true" type="java.util.Collection" %>
    

    ...I would have thought Java would be smart enough to figure that out on its own, but apparently not.