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

2563 questions
404
votes
8 answers

Evaluate empty or null JSTL c tags

How can I validate if a String is null or empty using the c tags of JSTL? I have a variable of name var1 and I can display it, but I want to add a comparator to validate it. I want to validate when it is null or empty (my…
user338381
  • 4,043
  • 3
  • 14
  • 4
259
votes
9 answers

Why JSF calls getters multiple times

Let's say I specify an outputText component like this: If I print a log message when the getter for someProperty is called and load the page, it is trivial to notice that the getter is being…
Sevas
  • 4,005
  • 3
  • 23
  • 26
131
votes
17 answers

Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable

When trying to reference a managed bean in EL like so #{bean.entity.property}, sometimes a javax.el.PropertyNotFoundException: Target Unreachable exception is being thrown, usually when a bean property is to be set, or when a bean action is to be…
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
123
votes
2 answers

Difference between JSP EL, JSF EL and Unified EL

I would like to know the detailed difference between the Expression Languages (EL). There is JSP EL, JSF EL and Unified EL. I would like to know the history behind the EL and what the latest EL is that is used in Java EE applications. Is it the EL…
Krishna
  • 6,706
  • 15
  • 64
  • 79
118
votes
7 answers

How do you get the length of a list in the JSF expression language?

How would I get the length of an ArrayList using a JSF EL expression? #{MyBean.somelist.length} does not work.
GBa
  • 14,931
  • 15
  • 47
  • 67
106
votes
12 answers

How to reference constants in EL?

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?
tau-neutrino
  • 3,150
  • 6
  • 22
  • 20
104
votes
4 answers

Use JSTL forEach loop's varStatus as an ID

I want to use the count from the JSTL forEach loop, but my code doesnt seem to work.
produces
Mark W
  • 5,416
  • 13
  • 52
  • 90
101
votes
4 answers

How do I check two or more conditions in one ?

How do I check two conditions in one ? I tried this, but it raises an error:
Selva Kumar K.P.
  • 1,039
  • 2
  • 10
  • 10
91
votes
3 answers

How to check a boolean condition in EL?

Is this correct? It's false! Or could I do this? It's false!
wiki
  • 3,049
  • 3
  • 18
  • 13
90
votes
9 answers

How to call a static method in JSP/EL?

I'm new to JSP. I tried connecting MySQL and my JSP pages and it works fine. But here is what I needed to do. I have a table attribute called "balance". Retrieve it and use it to calculate a new value called "amount". (I'm not printing "balance"). …
John
  • 9,897
  • 20
  • 63
  • 107
88
votes
2 answers

How does EL empty operator work in JSF?

In JSF an component can be rendered or not using the EL empty operator rendered="#{not empty myBean.myList}" As I've understood the operator works both as null-check, but also check checks if the list is empty. I want to do empty checks on some…
Aksel Willgert
  • 10,807
  • 5
  • 48
  • 70
85
votes
5 answers

EL access a map value by Integer key

I have a Map keyed by Integer. Using EL, how can I access a value by its key? Map map = new HashMap(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); I thought this would work but it doesn't (where map…
Steve Kuo
  • 58,491
  • 75
  • 189
  • 247
85
votes
2 answers

How to use && in EL boolean expressions in Facelets?

I am having a little trouble figuring out how to do and's on EL expressions in Facelets. So basically I have: But I keep…
Landister
  • 2,084
  • 6
  • 36
  • 51
81
votes
5 answers

What are the differences between ${} and #{}?

I'm programming in JSF2 and NetBeans creates many pages with #{} that contains an expression. However sometimes on the web I found ${} for the same thing! Are there any differences? What are they?
Filippo1980
  • 2,515
  • 5
  • 26
  • 42
79
votes
4 answers

JSP EL String concatenation

How do I concatenate strings in EL? I want to do something like this but it doesn't work: ${var1 == 0 ? 'hi' : 'hello ' + var2} It throws an exception trying to cast 'hello' to a Double
Kyle
  • 20,061
  • 36
  • 105
  • 192
1
2 3
99 100