EL (язык выражений) обеспечивает динамическое разрешение объектов и методов Java на страницах JSP и Facelets. Выражения EL имеют форму ${foo} и #{bar}.

Вступление

EL (язык выражений) обеспечивает динамическое разрешение объектов и методов Java на страницах JSP и Facelets. Выражения EL имеют форму${foo} а также #{bar}. Доллар (${}) и хеш (#{}) определяют выражения немедленной оценки и выражения отложенной оценки соответственно. Спецификация позволяет другим доменам применять свое собственное значение. В основном${} может только "получить", в то время как #{}может делать "получить" и "установить". Особенно "набор" является обязательным при использовании JSF фреймворка MVC. Таким образом, JSF может связать входные компоненты в представлении непосредственно с классом JavaBean в модели без необходимости в вашем собственном сервлете. ВFacesServlet затем сделает всю работу.

До JSP 2.0 (выпущенного в ноябре 2003 г.) EL был частью JSTL. Начиная с JSP 2.0, стандартный EL был перемещен из JSTL в JSP и поддерживается как часть спецификации JSP. JSTL 1.1 был первой версией, поставляемой без EL и использующей JSP EL. JSF также поддерживает собственную версию EL с отложенной оценкой.#{}. Начиная с JSP 2.1, отложенный EL был унифицирован со стандартным EL и поддерживается как отдельная спецификация, даже если они принадлежат одному и тому же JSR ( JSR 245). JSF 1.2 был первой версией, поставляемой без EL и использующей унифицированный EL. В EL 3.0 представлен даже новый автономный API процессора EL, так что его можно использовать автономно в простых проектах Java SE.

Текущая спецификация EL - JSR 341: Expression Language 3.0. В отличие от предыдущих версий EL, эта спецификация была размещена в собственном JSR.

См. Также разницу между JSP EL, JSF EL и Unified EL.


JavaBeans

Когда дело касается доступа к свойствам, EL полагается на спецификацию JavaBeans. В JSP следующее выражение

${user.name}

выполняет в основном то же самое, что и следующий код в "необработанном" коде скриптлета (приведенный ниже пример для простоты, в действительности API отражения используется для получения методов и их вызова):

<%
  User user = (User) pageContext.findAttribute("user");
  if (user != null) {
    String name = user.getName();
    if (name != null) {
      out.print(name);
    }
  }
%>

где PageContext#findAttribute() сканирует атрибуты соответственно PageContext (объем страницы), HttpServletRequest (объем запроса), HttpSession (объем сеанса) и ServletContext(область применения), пока не будет найдено первое ненулевое значение. Обратите внимание, что таким образом он не печатает"null" когда значение null ни бросает NullPointerExceptionв отличие от использования скриптлетов. Другими словами, EL нулевой.


Сделать объекты доступными для EL

Чтобы подготовить объекты для доступа к ним в JSP с помощью EL, все, что вам нужно сделать, это установить его как атрибут в желаемой области с помощью setAttribute()метод. Например, в сервлете предварительной обработки:

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);
}

В случае успешного входа в систему User объект в сеансе доступен ${user}в EL на протяжении всего сеанса. Все свойства стиля JavaBean доступны через${user.name}, ${user.email}, так далее.

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

В случае сбоя входа в систему сообщение доступно для ${message}в EL только в текущем запросе. Перенаправленный JSP может получить к нему доступ и отобразить его следующим образом.

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

Это значение исчезнет во всех последующих запросах, если сервлет не будет снова задан.

В JSTL есть <c:set> тег, который позволяет вам устанавливать атрибуты в желаемой области со стороны просмотра (а также был <c:remove> чтобы удалить его, но это было удалено). Например,

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

Это в основном следующее:

  • Если язык был указан как параметр запроса, он будет установлен.
  • В противном случае, если язык уже был установлен в сеансе, придерживайтесь его.
  • В противном случае используйте указанный пользователем языковой стандарт в заголовке запроса.

Пример взят из статьи Как интернационализировать веб-приложение Java?


Неявные объекты EL

В EL доступно несколько неявных объектов.

EL Scriptlet (out.print и нулевые проверки опущены!)
---------------------------------- ---------------- -----------------------------
${param.foo} request.getParameter("foo");
${paramValues.foo} request.getParameterValues ​​("foo");
${header['user-agent']} request.getHeader("user-agent");
${pageContext.request.contextPath} request.getContextPath();
${cookie.somename} Слишком подробно (начните с request.getCookies())

В JSF (и большинстве других фреймворков MVC) запрос сервлета HTTP, сеанс и другие доступны напрямую через ${request}, ${session}и т. д. без необходимости получать их PageContext.

Также доступны неявные сопоставления атрибутов для каждой области: ${pageScope}, ${requestScope}, ${sessionScope} а также ${applicationScope}. Это полезно в случае, когда у вас есть атрибуты с одним и тем же именем в разных областях (что само по себе на самом деле является плохим дизайном, но это в стороне). Например, если у вас есть"user" атрибут, который доступен как в области запроса, так и в области сеанса, тогда ${user}вернет тот, который находится в области запроса. Чтобы в любом случае явно получить доступ к тому, который находится в области сеанса, вам понадобится${sessionScope.user}.

В JSF доступно гораздо больше неявных объектов. Вы можете найти их все здесь.


Обозначение скобок

Вы можете использовать так называемые фигурные скобки [] для доступа к свойствам по динамическому имени, для доступа к значениям карты с помощью ключа, содержащего точки, для использования имен / ключей, которые сами по себе являются зарезервированными литералами в Java, и для доступа к элементам массива или списка по индексу.

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

Вышеупомянутое по существу то же, что

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

Вызов методов без получения

Начиная с EL 2.2, который поддерживается как часть Servlet 3.0 / JSP 2.2 (Tomcat 7, Glassfish 3, JBoss AS 6 и т. Д.), Можно при необходимости вызывать методы без получения с аргументами.

Например

${bean.find(param.id)}

с

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

вызовет метод с request.getParameter("id") как аргумент.

Обратите внимание, что EL не поддерживает перегрузку метода, поскольку преобразователь EL не требуется для проверки типа (ов) аргумента.

Распространенное заблуждение состоит в том, что эта функция является частью JSF 2.0, но это не так. EL 2.2 и JSF 2.0 случится и будут включены в Java EE 6 API и, таким образом, как правило, встречаются вместе. Однако JSF 2.0 обратно совместим с Servlet 2.5 (Java EE 5; поставляется с EL 2.1), который не имеет этой функции.

Таким образом, при использовании JSF 2.0 в контейнере Servlet 2.5 вы определенно пропустите эту функцию EL 2.2, и вам нужно будет установить JBoss EL, чтобы получить ту же функцию в EL 2.1. Обратите внимание, что это также означает, что вы можете просто использовать EL 2.2 (или хотя бы JBoss EL) в сочетании с JSF 1.x.


EL функции

Вы можете объявить public staticслужебные методы как функции EL (например, как функции JSTL), чтобы вы могли использовать их в EL. Например

package com.example;

public final class Functions {
     private Functions() {}

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

с /WEB-INF/functions.tld которые выглядят следующим образом:

<?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>

который можно использовать как

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

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

Вы даже можете ссылаться на существующие служебные функции, например Apache Commons Lang StringEscapeUtils#escapeEcmaScript() (или StringEscapeUtils#escapeJavaScript() при использовании 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>

который можно использовать как

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

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

(обратите внимание, что эти кавычки являются обязательными для представления строковой переменной JS, они вообще не имеют ничего общего с функцией EL)

При использовании преемника JSPFacelets вместо JSP перейдите к этому ответу, чтобы узнать, как создать функцию EL для Facelets: Как создать настраиваемую функцию EL для вызова статического метода? Основное отличие заключается в файле taglib.


Характеристики


Ссылки


Часто задаваемые вопросы


Информационные страницы связанных тегов