Accessing Java Constants from JSTL

4 min read >

Accessing Java Constants from JSTL

Engineering Insights & Enterprise solutions

It’s been a while now since the first specifications of JSTL. Since then it emerged as a standard for the presentation layer in web applications, replacing the ugly scriptlets with nice-looking tags that resemble the HTML or XML markup. JSTL provides tags for typical presentation layer tasks, such as iterations, conditional content, data formatting, XML manipulation, and database access, and its expression language makes working with dynamic attribute values a lot easier.

If you have used EL before, notations like:

${object}

may look familiar. The EL supports accessing fields of objects and elements of collections by using its defined accessors (dot and brackets). Though these accessors may be used interchangeably, it is recommended to use dots for accessing members and brackets for collections.

${user.phone} - the equivalent of user.getPhone()

and

${users[2]} - the equivalent of users.get(2) where users is a List

or

${users["John"]} - the equivalent of users.get("John") where users is a Map

Looking at the last example, what happens when you want to use in your application constants for the keys in your map. Supposing that you have a Constants class:

class Constants {

public static final String NAME = "name";

}

a notation like this:

${users[Constants.NAME]}

will not work. That’s because the Constants class is not by default available to any of the web contexts, hence is not accessible by the EL expressions. Second, if you would make it available through <jsp:useBean> tag, a constants class by its nature will not follow the Java Beans properties accessors specifications (i.e. in our case it will not have getters for its fields).

To use such a class we have to present it to the EL in a way that it can access it. A Map is a good solution for this. The idea is to implement a method to look to a Constants class through reflection, make a Map with all its public static final fields, and use that Map in EL. Here is one idea of how to do this:

Class c = Constants.getClass();
Field[] fields = c.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
int modifier = field.getModifiers();
if (Modifier.isFinal(modifier) && !Modifier.isPrivate(modifier))
try {
this.put(field.getName(), field.get(this));
}
catch (IllegalAccessException e) {}
}

You can use this code to create the desired Map and place this Map somewhere in the ApplicationContext for further usage.

Even though there could be many variations to the above code, more creative, funnier, or smarter, this is not my recommended solution. Following Principle No. 6 from our internal guide, the “DRW concept” (don’t reinvent the wheel 🙂 ), the solution is simple: the unstandard tag library from Apache. Here’s how to use it:

<%@ taglib prefix="un" uri="http://jakarta.apache.org/taglibs/unstandard-1.0"%>

<un:useConstants var="Constants" className="com......Constants" />

and later in your code, an expression like:

${users[Constants.NAME]}

will work like a charm.