EL (Expression Language) enables the dynamic resolution of Java objects and methods in JSP and Facelets pages. EL expressions take the form of ${foo} and #{bar}. The dollar (${}) and hash (#{}) define immediate evaluation expressions and deferred evaluation expressions respectively. The specification allows that other domains can apply their own meaning. Basically, the ${} can only do "get", while the #{} can do "get" and "set". Especially the "set" is mandatory when using the MVC framework JSF. This way JSF can bind the input components in the view directly to a JavaBean class in the model without the need for your own servlet. The FacesServlet will then do all the work.

Before JSP 2.0 (released Nov 2003), EL was part of JSTL. Since JSP 2.0, standard EL was moved from JSTL to JSP and maintained as part of the JSP specification. JSTL 1.1 was the first version to ship without EL and make use of JSP EL. JSF also maintained its own version of EL with deferred evaluation #{}. Since JSP 2.1, deferred EL was unified with standard EL and is maintained as a separate specification, even though they belong to the same JSR (JSR 245). JSF 1.2 was the first version to ship without EL and make use of unified EL. In the EL 3.0, even a new standalone EL processor API is introduced so that it can be used standalone in simple Java SE projects.

The current EL specification is JSR 341: Expression Language 3.0. Unlike the previous EL versions, this specification was placed in its own JSR.

See also Difference between JSP EL, JSF EL and Unified EL.


EL relies on the JavaBeans specification when it comes to accessing properties. In JSP, the following expression


does basically the same as the following in "raw" scriptlet code (the below example is for simplicity, in reality the reflection API is used to obtain the methods and invoke them):

  User user = (User) pageContext.findAttribute("user");
  if (user != null) {
    String name = user.getName();
    if (name != null) {

where PageContext#findAttribute() scans the attributes of respectively the PageContext (page scope), HttpServletRequest (request scope), HttpSession (session scope) and ServletContext (application scope) until the first non-null value is found. Please note that it thus doesn't print "null" when the value is null nor throws a NullPointerException unlike as when using scriptlets. In other words, EL is null-safe.

Make objects available to EL

To prepare objects so that they can be accessed in JSP by EL, all you need to do is to set it as an attribute in the desired scope by the setAttribute() method. For example as follows in a preprocessing servlet:

String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);

if (user != null) { 
  request.getSession().setAttribute("user", user); // Make available by ${user} in session scope.
} else {
  request.setAttribute("message", "Unknown login, try again"); // Make available by ${message} in request scope.

If the login succeeds, the User object in session is available by ${user} in EL throughout the entire session. All of the JavaBean style properties are accessible by ${user.name}, ${user.email}, etc.

<c:if test="${user != null}">
  <p>Welcome, ${user.name}</p>

If the login fails, the message is available by ${message} in EL in the current request only. The forwarded JSP is able to access and display it as follows.

<span class="error">${message}</span>

This value will disappear in all subsequent requests when not set again by a servlet.

In JSTL, there's the <c:set> tag which allows you to set attributes in the desired scope from the view side on (and there's also a <c:remove> to remove it). For example,


This does basically the following:

  • If the language was supplied as request parameter, then it will be set.
  • Else use the user supplied locale in the request header.

The example is taken from How to internationalize a Java web application?

Implicit EL objects

In EL there are several implicit objects available.

EL                                  Scriptlet (out.print and null checks omitted!)
${param.foo}                        request.getParameter("foo");
${paramValues.foo}                  request.getParameterValues("foo");
${header['user-agent']}             request.getHeader("user-agent");
${pageContext.request.contextPath}  request.getContextPath();
${cookie.somename}                  Too verbose (start with request.getCookies())

In JSF (and most of other MVC frameworks) the HTTP servlet request, session and others are available directly by ${request}, ${session}, etc without the need to get them by PageContext.

There are also implicit attribute mappings available per scope: ${pageScope}, ${requestScope}, ${sessionScope} and ${applicationScope}. This is useful for the case when you have attributes with the same name in different scopes (which at its own is actually a bad design, but that aside). For example, when you have an "user" attribute which is available in both the request and session scope, then ${user} would return the one in the request scope. To explicitly access the one in the session scope anyway, you would need ${sessionScope.user}.

In JSF there are many more implicit objects available. You can find them all here.

Brace notation

You can use the so-called brace notation [] to access properties by a dynamic name, to access map values by a key containing periods, to use names/keys which are by itself reserved literals in Java and to access array or list items by index.


The above does essentially the same as


Invoking non-getter methods

Since EL 2.2, which is maintained as part of Servlet 3.0 / JSP 2.2 (Tomcat 7, Glassfish 3, JBoss AS 6, etc), it's possible to invoke non-getter methods, if necessary with arguments.




public Something find(String id) {
    return someService.find(id);

will invoke the method with request.getParameter("id") as argument.

Note that EL does not support method overloading since the EL resolver is not required to check the argument's type(s).

A common confusion is that this feature is part of JSF 2.0. This is thus not true. EL 2.2 and JSF 2.0 happen to be both part of the Java EE 6 API and are thus usually found together. JSF 2.0 is in turn however backwards compatible with Servlet 2.5 (Java EE 5; ships with EL 2.1). So when using JSF 2.0 on a Servlet 2.5 container, you'll definitely miss this EL 2.2 feature and you'd need to install JBoss EL to get the same feature in EL 2.1. Note that this also means that you can just use EL 2.2 (or at least JBoss EL) in combination with JSF 1.x.

EL functions


package com.example;

public final class Functions {
     private Functions() {}

     public static boolean matches(String string, String pattern) {
         return string.matches(pattern);

with /WEB-INF/functions.tld which look like follows:




which can be used as



You can even refer existing utility functions, for example the Apache Commons Lang StringEscapeUtils#escapeEcmaScript() (or StringEscapeUtils#escapeJavaScript() when still using Lang 2.x)

        <function-signature>java.lang.String escapeEcmaScript(java.lang.String)</function-signature>

which can be used as


    var foo = "${f:escapeJS(bean.foo)}";

(please note that those quotes are mandatory to represent a JS string variable, they have nothing to do with the EL function at all)

When using JSP's successor Facelets instead of JSP, then head to this answer to learn how to create an EL function for Facelets: How to create a custom EL function? The main difference is in the taglib file.



Frequently asked questions

Related tag info pages

history | show excerpt | excerpt history