arraysjspel

Array literals in JSP Expression Language?


I've been able to do Array literals in Thymeleaf's expression language before (using...OGNL?...I think...). Now I am using Spring/JSP. Do the JSP or Spring Expression Languages support Array Literals? I can't find any reference to them.

This is basically what I'm trying to do:

<c:set var="myUrls" value="${new String[] {
    mk:getUrl(),
    mk:getOtherUrl(),
    mk:getDifferentUrl()
}}" />

Solution

  • If you're already on EL 3.0 or newer (Tomcat 8+ or equivalent), then you can use ${[ ... ]} to construct a List:

    <c:set var="list" value="${[mk:getUrl(), mk:getOtherUrl(), mk:getDifferentUrl()]}" />
    
    <c:forEach items="${list}" var="item">
        ${item}<br/>
    </c:forEach>
    

    Or ${{ ... }} to construct a Set:

    <c:set var="set" value="${{mk:getUrl(), mk:getOtherUrl(), mk:getDifferentUrl()}}" />
    
    <c:forEach items="${set}" var="item">
        ${item}<br/>
    </c:forEach>
    

    If you're not on EL 3.0 yet but your environment supports EL 2.2 (Tomcat 7 or equivalent), then you could hack it together with a little help of <jsp:useBean> and a LinkedHashMap.

    <jsp:useBean id="map" class="java.util.LinkedHashMap" />
    <c:set target="${map}" property="url" value="${mk.url}" />
    <c:set target="${map}" property="otherUrl" value="${mk.otherUrl}" />
    <c:set target="${map}" property="differentUrl" value="${mk.differentUrl}" />
    <c:set var="array" value="${map.values().toArray()}" />
    
    <c:forEach items="${array}" var="item">
        ${item}<br/>
    </c:forEach>
    

    If your environment doesn't even support EL 2.2 (Tomcat 6- or equivalent), then just skip array creation and access the LinkedHashMap directly.

    <jsp:useBean id="map" class="java.util.LinkedHashMap" />
    <c:set target="${map}" property="url" value="${mk.url}" />
    <c:set target="${map}" property="otherUrl" value="${mk.otherUrl}" />
    <c:set target="${map}" property="differentUrl" value="${mk.differentUrl}" />
    
    <c:forEach items="${map}" var="entry">
        ${entry.value}<br/>
    </c:forEach>
    

    Noted should be that your underlying problem is probably bigger. You shouldn't be manipulating the model directly in the view. The controller is responsible for that. You should be altering the model in such way so that it's exactly what the view expects. E.g. by adding a property, or by letting the controller do the job.