Question

I'm working on a web application using Java and its frameworks(Spring 3.1.1). And I'm trying to avoid using scriptlets as much as possible, however I can't find a way other than this to define an array:

<%
    String[] alphabet = {"A", "B", "C", ... , "Z"};
    pageContext.setAttribute("alphabet", alphabet);      
%> 

After setting pageContext attribute, I can use it with ${alphabet}. But I want to know, is it possible to use plain JSTL/EL to create an array?

UPDATE: I'm using this array to create links. For example, if user clicks 'S', a list of employees whose first name starts with 'S' comes. So, instead of creating links one by one I'm iterating ${alphabet}.

Was it helpful?

Solution

If you're already on EL 3.0 (Tomcat 8+, WildFly 8+, GlassFish 4+, Payara 4+, TomEE 7+, etc), which supports new operations on collection objects, you can use ${[...]} syntax to construct a list, and ${{...}} syntax to construct a set.

<c:set var="alphabet" value="${['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']}" scope="application" />

If you're not on EL 3.0 yet, use the ${fn:split()} function trick on a single string which separates the individual characters by a common separator, such as comma.

<c:set var="alphabet" value="${fn:split('A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z', ',')}" scope="application" />

I do however agree that you're better off using normal Java code for this. Given that it's apparently static data, just create this listener class:

@WebListener
public class ApplicationData implements ServletContextListener {

    private static final String[] ALPHABET = { "A", "B", "C", ..., "Z" };

    @Override
    public void contextInitialized(ServletContextEvent event) {
        event.getServletContext().setAttribute("alphabet", ALPHABET);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // NOOP.
    }

}

It'll transparently auto-register itself on webapp's startup and put the desired data in application scope.

OTHER TIPS

If you want to iterate over tokens in string then simply use forTokens:

<c:set var="alphabet">A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z</c:set>

<c:forTokens items="${alphabet}" delims="," var="letter">
    ${letter}
</c:forTokens>

If you use Java EE 7 / Expression Language 3.0 you can create a List literal

<c:set var="alphabet" value="${['A', 'B', 'C', ... , 'Z']}" />

which can then iterate over much like an Array.

JSP's are not intended for this kind of stuffs. They are meant to consume, not create. If you want to create an array, then you probably need a Servlet here.

Add the logic of array creation (or even better, List creation), in a Servlet, and use it to pre-process the request to your JSP page. And then, you can use the List attribute set in the servlet in your JSP page.

Not pure EL, but a pretty clean solution nevertheless:

<c:set var="alphabet" value='<%=new String[]{"A", "B"} %>'/>

Without knowing which framework are you using, the best approach to work with JSPs without using is scriptlets is to back every JSP (view) with a Java bean (an object):

Backing bean:

public class MyBackingBean {

   private List<String> alphabet;

   public List<String> getAlphabet() {
      if (alphabet == null) {
         // Using lazy initialization here, this could be replaced by a
         // database lookup or anything similar
         alphabet= Arrays.asList(new String[]{ "A", "B", "C", ... });
      }
      return alphabet;
   }

}

Then instantiate the bean at the JSP this way:

<jsp:useBean id="backingBean" scope="page" class="com.example.MyBackingBean" />

After that, you could use the EL ${backingBean.alphabet} to access that list.

Note: if you need more complex processing then you will have to use Servlets or any of the features provided by any framework.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top