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
31
votes
6 answers

How can I pass an object to a JSP tag?

I have a JSP page that contains a scriplet where I instantiate an object. I would like to pass that object to the JSP tag without using any cache. For example I would like to accomplish this: <%@ taglib prefix="wf" uri="JspCustomTag" %> <% …
Joe Bienkowski
  • 311
  • 1
  • 3
  • 3
31
votes
2 answers

Access the size of a collection in JSP/JSTL/EL

I have a List variable called services in my JSP page. I need to add some markup to the page if there's more than 1 element in the list. What I'd like to do is... But you can't…
Drew Wills
  • 8,408
  • 4
  • 29
  • 40
30
votes
9 answers

JSP: EL expression is not evaluated

I have a JSP page running on Tomcat 5.5. I have the following code:
The output I am getting is: ${i} ${i} ${i} ${i} ${i} ${i} ${i} ${i} ${i}…
James
30
votes
6 answers

Creating Array using JSTL or EL

I'm working on a web application using Java and its frameworks(Spring 3.1.1). And I'm trying to avoid using scriptlets as much as possible, however I can't find a way other than this to define an array: <% String[] alphabet = {"A", "B", "C", ...…
Alpha Carinae
  • 441
  • 2
  • 8
  • 11
28
votes
2 answers

Invoke direct methods or methods with arguments / variables / parameters in EL

How can I in JSF 2.0 invoke direct methods or methods with arguments / variables / parameters in EL? For example, getting the list size in EL: Or invoking an action method with…
DD.
  • 21,498
  • 52
  • 157
  • 246
28
votes
1 answer

Is it possible to use EL conditional operator in action attribute?

The conditional operator works in many attributes like "rendered" "value" and others. But it does not work in action? Or am I doing it wrong? Error: javax.el.ELException:…
djmj
  • 5,579
  • 5
  • 54
  • 92
27
votes
3 answers

Expression Language & Eclipse warning: "items" does not support runtime expressions

i have the following JSP: <%@ page contentType="text/html" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <%@ page isELIgnored="false"%>
fasseg
  • 17,504
  • 8
  • 62
  • 73
27
votes
4 answers

How to pass parameter to jsp:include via c:set? What are the scopes of the variables in JSP?

I have this on welcome.jsp And this in head.jsp: Site Name - ${pgTitle} But the variable is blank, and the output is merely Site Name - I have read…
vcardillo
  • 1,646
  • 3
  • 24
  • 29
27
votes
2 answers

javax.el.PropertyNotFoundException: Property 'foo' not readable on type java.lang.Boolean

I have a class which looks something like this: public class ScoreDefinition { protected Boolean primary; public Boolean isPrimary() { return primary; } public void setPrimary(Boolean value) { this.primary =…
user1759136
27
votes
4 answers

How to access a request attribute set by a servlet in JSP?

I'm trying to retrieve attribute values set by a servlet in a JSP page, but I've only luck with parameters by ${param}. I'm not sure about what can I do different. Maybe its simple, but I couldn't manage it yet. public void…
Alex
  • 3,325
  • 11
  • 52
  • 80
26
votes
1 answer

Specify conditional rendering of element inside ? The does not seem to work

I am trying to conditionally build a custom list using . On every occurrence of -1 as item-value in list, I need to add a line break. I tried to use inside for that, but it does not seem to work. It always evaluates…
Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294
26
votes
5 answers

How to concatenate a String in EL?

How do I get the promoPrice variable to print as part of the string ONLY $4.67?

${(promoPrice != null) ? "ONLY $${promoPrice}" : "FREE"}

alquatoun
  • 580
  • 1
  • 5
  • 19
26
votes
3 answers

Why there is a need of pageContext in JSP?

When we can access all the implicit variables in JSP, why do we have pageContext ? My assumption is the following: if we use EL expressions or JSTL, to access or set the attributes we need pageContext. Let me know whether I am right.
Dead Programmer
  • 12,427
  • 23
  • 80
  • 112
25
votes
1 answer

How to set -Dorg.apache.el.parser.COERCE_TO_ZERO=false programmatically

This question is similar to: jsf: integer property binded to a inputtext in UI is set to zero on submit but I am not completely satisfied with the solution. The contexts is the same: I have a web form requiring an Integer value. If the textbox is…
Steve
  • 11,831
  • 14
  • 51
  • 63
25
votes
1 answer

JSF: h:outputText; how to show a dash when the value is empty string?

I'm using h:outputText tags to display readonly data. Ex: When "phoneNumber" is an empty string or a null, I want to display a dash "-" as the…
user550738