Questions tagged [el]

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}.

Introduction

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.


JavaBeans

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

${user.name}

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) {
      out.print(name);
    }
  }
%>

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.
  response.sendRedirect("userhome");
} else {
  request.setAttribute("message", "Unknown login, try again"); // Make available by ${message} in request scope.
  request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}

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>
</c:if>

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 was also a <c:remove> to remove it, but this has been removed). For example,

<c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" />

This does basically the following:

  • If the language was supplied as request parameter, then it will be set.
  • Else if the language was already previously set in the session, then stick to it instead.
  • 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.

${sessionScope[dynamicName]}
${someMap[dynamicKey]}
${someMap['key.with.periods']}
${some['class'].simpleName}
${someList[0].name}
${someArray[0].name}

The above does essentially the same as

session.getAttribute(dynamicName);
someMap.get(dynamicKey);
someMap.get("key.with.periods");
some.getClass().getSimpleName();
someList.get(0).getName();
someArray[0].getName();

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.

E.g.

${bean.find(param.id)}

with

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, but this is not true. EL 2.2 and JSF 2.0 happen to both be included in the Java EE 6 API and thus are usually found together. However, JSF 2.0 is backwards compatible with Servlet 2.5 (Java EE 5; ships with EL 2.1), which does not have this feature.

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

You can declare public static utility methods as EL functions (like as JSTL functions) so that you can use them in EL. E.g.

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:

<?xml version="1.0" encoding="UTF-8" ?>
<taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

    <tlib-version>1.0</tlib-version>
    <short-name>Custom_Functions</short-name>
    <uri>http://example.com/functions</uri>

    <function>
        <name>matches</name>
        <function-class>com.example.Functions</function-class>
        <function-signature>boolean matches(java.lang.String, java.lang.String)</function-signature>
    </function>
</taglib>

which can be used as

<%@taglib uri="http://example.com/functions" prefix="f" %>

<c:if test="${f:matches(bean.value, '^foo.*')}">
    ...
</c:if>

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>
        <name>escapeJS</name>
        <function-class>org.apache.commons.lang3.StringEscapeUtils</function-class>
        <function-signature>java.lang.String escapeEcmaScript(java.lang.String)</function-signature>
    </function>

which can be used as

<%@taglib uri="http://example.com/functions" prefix="f" %>

<script>
    var foo = "${f:escapeJS(bean.foo)}";
    ...
</script>

(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 to invoke a static method? The main difference is in the taglib file.


Specifications


References


Frequently asked questions


Related tag info pages

2589 questions
67
votes
1 answer

Method must have signature "String method() ...[etc]..." but has signature "void method()"

I have a datatable with a button in each row: In the backing bean there's this…
hugri
  • 1,416
  • 3
  • 18
  • 32
66
votes
2 answers

Defining and reusing an EL variable in JSF page

Is it possible to define variable and reuse the variable later in EL expressions ? For example : What i have in mind is…
Bertie
  • 17,277
  • 45
  • 129
  • 182
65
votes
3 answers

Format Date output in JSF

If #{myBean.birthdate} is of java.util.Calendar or java.util.Date type, can I possibly format this inside the EL itself using an existing function perhaps, with the output of like the one produced by the DateFormat's SHORT, MEDIUM,LONG abd FULL…
Bertie
  • 17,277
  • 45
  • 129
  • 182
62
votes
3 answers

How to access at request attributes in JSP?

Currently I use: <% final String message = (String) request.getAttribute ("Error_Message"); %> and then <%= message %> However I wonder if the same can be done with EL or JSTL instead of using a scriptlet.
Martin
  • 11,577
  • 16
  • 80
  • 110
61
votes
7 answers

String Concatenation in EL

I would like to concatenate a string within a ternary operator in EL(Expression Language). Suppose there is a variable named value. If it's empty, I want to use some default text. Otherwise, I need to append it with some static text. ${(empty…
Tom Tucker
  • 11,676
  • 22
  • 89
  • 130
55
votes
1 answer

null check in jsf expression language

Please see this Expression Language styleClass="#{obj.validationErrorMap eq null ? ' ' : obj.validationErrorMap.contains('key')?'highlight_field':'highlight_row'}" Even if the map is null, highlight_row style is getting applied. So I changed…
crazyTechie
  • 2,517
  • 12
  • 32
  • 41
54
votes
3 answers

How to testing for enum equality in JSF?

Is it possible to test for enum equality in JSF? E.g. where stuff is an enum Stuff:
DD.
  • 21,498
  • 52
  • 157
  • 246
52
votes
2 answers

how to debug JSF/EL

How to debug EL in the JSF page? I'd like to watch variable values, function calls an so on. The best solution would be an eclipse plugin, but any other possibility is better than guessing "Why this expression failed to render correctly?".
mrzasa
  • 22,895
  • 11
  • 56
  • 94
52
votes
1 answer

How to create a custom EL function to invoke a static method?

Im new to JSF 2. My question is related to BalusC's answer to this question jsf2 ajax update parts based on request parameters I tried the kickstart code BalusC posted and I encountered an EL parsing error: /nameofpage.xhtml @12,64…
royjavelosa
  • 2,048
  • 6
  • 30
  • 46
48
votes
3 answers

Should I choose == or eq for comparing string in EL?

== and eq give the same result using EL to do my string comparison tests: Endast USA Alla länder
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
47
votes
2 answers

Concat two String in JSF EL expression

I have the following el expression: But I am getting…
Tapas Bose
  • 28,796
  • 74
  • 215
  • 331
47
votes
3 answers

Check if parameter exists in Expression Language

How do I check if param.username exists??
Borut Flis
  • 15,715
  • 30
  • 92
  • 119
45
votes
4 answers

How to call parameterized method from JSP using JSTL/EL

How to call a Java method with arguments which is defined in Java class, from JSP using JSTL/EL. The method is returning arrays. Any return value can be used.
sachin gk
  • 585
  • 3
  • 6
  • 11
45
votes
2 answers

How to compare two object variables in EL expression language?

I am creating a drop down list of all languages. The default language selection for the list will be determined by information added by the user: