How to reference constants in EL?

Viewed 71132

How do you reference an constants with EL on a JSP page?

I have an interface Addresses with a constant named URL. I know I can reference it with a scriplet by going: <%=Addresses.URL%>, but how do I do this using EL?

12 Answers

I'm defining a constant in my jsp right at the beginning:

<%final String URI = "http://www.example.com/";%>

I include the core taglib in my JSP:

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

Then, I make the constant available to EL by following statement:

<c:set var="URI" value="<%=URI%>"></c:set>

Now, I can use it later. Here an example, where the value is just written as HTML comment for debugging purposes:

<!-- ${URI} -->

With your constant class, you can just import your class and assign the constants to local variables. I know that my answer is a sort of quick hack, but the question also bumps up when one wants to define constants directly in the JSP.

Yes, you can. You need a custom tag (if you can't find it somewhere else). I've done this:

package something;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;

/**
 * Get all class constants (statics) and place into Map so they can be accessed
 * from EL.
 * @author Tim.sabin
 */
public class ConstMapTag extends TagSupport {
    public static final long serialVersionUID = 0x2ed23c0f306L;

    private String path = "";
    private String var = "";

    public void setPath (String path) throws JspException {
        this.path = (String)ExpressionUtil.evalNotNull ("constMap", "path",
          path, String.class, this, pageContext);
    }

    public void setVar (String var) throws JspException {
        this.var = (String)ExpressionUtil.evalNotNull ("constMap", "var",
          var, String.class, this, pageContext);
    }

    public int doStartTag () throws JspException {
        // Use Reflection to look up the desired field.
        try {
            Class<?> clazz = null;
            try {
                clazz = Class.forName (path);
            } catch (ClassNotFoundException ex) {
                throw new JspException ("Class " + path + " not found.");
            }
            Field [] flds = clazz.getDeclaredFields ();
            // Go through all the fields, and put static ones in a Map.
            Map<String, Object> constMap = new TreeMap<String, Object> ();
            for (int i = 0; i < flds.length; i++) {
                // Check to see if this is public static final. If not, it's not a constant.
                int mods = flds [i].getModifiers ();
                if (!Modifier.isFinal (mods) || !Modifier.isStatic (mods) ||
                  !Modifier.isPublic (mods)) {
                    continue;
                }
                Object val = null;
                try {
                    val = flds [i].get (null);    // null for static fields.
                } catch (Exception ex) {
                    System.out.println ("Problem getting value of " + flds [i].getName ());
                    continue;
                }
                // flds [i].get () automatically wraps primitives.
                // Place the constant into the Map.
                constMap.put (flds [i].getName (), val);
            }
            // Export the Map as a Page variable.
            pageContext.setAttribute (var, constMap);
        } catch (Exception ex) {
            if (!(ex instanceof JspException)) {
                throw new JspException ("Could not process constants from class " + path);
            } else {
                throw (JspException)ex;
            }
        }
        return SKIP_BODY;
    }
}

and the tag is called:

<yourLib:constMap path="path.to.your.constantClass" var="consts" />

All public static final variables will be put into a Map indexed by their Java name, so if

public static final int MY_FIFTEEN = 15;

then the tag will wrap this in an Integer and you can reference it in a JSP:

<c:if test="${consts['MY_FIFTEEN'] eq 15}">

and you don't have to write getters!

Related