Перейти к основному содержимому

Введение в JSF EL 2

· 7 мин. чтения

1. Введение

Язык выражений (EL) — это язык сценариев, который был принят во многих средах Java, таких как Spring с SpEL и JBoss с JBoss EL.

В этой статье мы сосредоточимся на реализации JSF этого языка сценариев — Unified EL.

В настоящее время EL находится в версии 3.0, крупном обновлении, которое позволяет использовать механизм обработки в автономном режиме, например, на платформе Java SE. Предыдущие версии зависели от сервера приложений или веб-контейнера, совместимого с Jakarta EE. В этой статье обсуждается EL версии 2.2.

2. Немедленная и отложенная оценка

Основная функция EL в JSF — соединить представление JSF (обычно XHTML-разметку) и серверную часть на основе Java. Серверная часть может представлять собой управляемые компоненты, созданные пользователем, или объекты, управляемые контейнером, такие как сеанс HTTP.

Мы будем смотреть на EL 2.2. EL в JSF существует в двух основных формах: непосредственный синтаксис EL и отложенный синтаксис EL.

2.1. Непосредственный синтаксис EL

Также известный как JSP EL, это формат сценариев, пережиток времен JSP разработки веб-приложений на Java.

Выражения JSP EL начинаются со знака доллара ( $ ), затем следует левая фигурная скобка ( { ), затем следует фактическое выражение и, наконец, закрывается правой фигурной скобкой ( } ):

${ELBean.value > 0}

Этот синтаксис:

  1. Оценивается только один раз (в начале) в жизненном цикле страницы. Это означает, что значение, которое есть. Быть прочитанным выражением в приведенном выше примере должно быть установлено до загрузки страницы.
  2. Предоставляет доступ только для чтения к значениям компонента.
  3. И, как следствие, требует соблюдения соглашения об именах JavaBean.

Для большинства применений эта форма EL не очень универсальна.

2.2. Отложенное выполнение EL

Deferred Execution EL — это EL, разработанный для собственно JSF. Основное синтаксическое отличие от JSP EL заключается в том, что он помечен знаком « вместо « $ ».

#{ELBean.value > 0}

Отложенный ЭЛ:

  1. Синхронизируется с жизненным циклом JSF. Это означает, что выражение EL в отложенном EL оценивается в разные моменты рендеринга страницы JSF (в начале и в конце).
  2. Предоставляет доступ для чтения и записи к значениям компонента. Это позволяет установить значение в вспомогательном компоненте JSF (или где-либо еще) с помощью EL.
  3. Позволяет программисту вызывать произвольные методы для объекта и, в зависимости от версии EL, передавать аргументы таким методам.

Unified EL — это спецификация, объединяющая как deferred EL, так и JSP EL, позволяя использовать оба синтаксиса на одной странице.

3. Унифицированный ЭЛ

Unified EL допускает два основных вида выражений: выражения значений и выражения методов.

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

http://localhost:8080/jsf/el_intro.jsf

3.1. Выражения значений

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

Следующее выражение считывает свойство управляемого компонента на страницу:

Hello, #{ELBean.firstName}

Однако следующее выражение позволяет нам установить значение для пользовательского объекта:

<h:inputText id="firstName" value="#{ELBean.firstName}" required="true"/>

Переменная должна соответствовать соглашению об именах JavaBean, чтобы иметь право на такое обращение. Чтобы значение bean-компонента было зафиксировано, нужно просто сохранить закрывающую форму.

3.2. Выражения методов

Unified EL предоставляет выражения методов для выполнения общедоступных нестатических методов на странице JSF. Методы могут иметь или не иметь возвращаемых значений.

Вот краткий пример:

<h:commandButton value="Save" action="#{ELBean.save}"/>

Упомянутый метод save() определен в компоненте поддержки с именем ELBean.

Начиная с EL 2.2, вы также можете передавать аргументы методу, доступ к которому осуществляется с помощью EL. Это может позволить нам переписать наш пример следующим образом:

<h:inputText id="firstName" binding="#{firstName}" required="true"/>
<h:commandButton value="Save"
action="#{ELBean.saveFirstName(firstName.value.toString().concat('(passed)'))}"/>

Здесь мы создали выражение привязки на уровне страницы для компонента inputText и напрямую передали атрибут value в выражение метода.

Обратите внимание, что переменная передается в метод без каких-либо специальных обозначений, фигурных скобок или escape-символов.

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

Механизм JSF EL обеспечивает доступ к нескольким объектам, управляемым контейнером. Некоторые из них:

  • #{Application} : также доступен как #{servletContext} , это объект, представляющий экземпляр веб-приложения.
  • #{applicationScope} : карта переменных, доступных для всего веб-приложения.
  • #{Cookie} : карта переменных HTTP Cookie
  • #{facesContext} : текущий экземпляр FacesContext
  • #{flash} : объект JSF Flash с областью действия
  • #{header} : карта заголовков HTTP в текущем запросе.
  • #{initParam} : карта переменных инициализации контекста веб-приложения.
  • #{param} : карта параметров запроса HTTP-запроса
  • #{request} : объект HTTPServletRequest
  • #{requestScope} : карта переменных в области запроса
  • #{sessionScope} : карта переменных на уровне сеанса
  • #{session} : объект HTTPSession
  • #{viewScope} : карта переменных в области просмотра (страницы)

В следующем простом примере перечислены все заголовки и значения запроса путем доступа к неявному объекту заголовков :

<c:forEach items="#{header}" var="header">
<tr>
<td>#{header.key}</td>
<td>#{header.value}</td>
</tr>
</c:forEach>

4. Что вы можете сделать в EL

Благодаря своей универсальности EL может использоваться в коде Java, разметке XHTML, Javascript и даже в файлах конфигурации JSF, таких как файлfaces-config.xml . Давайте рассмотрим некоторые конкретные варианты использования.

4.1. Используйте EL в разметке страницы

EL может быть представлен в стандартных тегах HTML:

<meta name="description" content="#{ELBean.pageDescription}"/>

4.2. Используйте EL в JavaScript

EL будет интерпретироваться при обнаружении в тегах Javascript или <script>:

<script type="text/javascript"> var theVar = #{ELBean.firstName};</script>

Переменная поддерживающего компонента будет установлена здесь как переменная javascript.

4.3. Оцените логическую логику в EL с помощью операторов

EL поддерживает довольно продвинутые операторы сравнения:

  • eq оператор равенства, эквивалентный « ==».
  • lt меньше, чем оператор, эквивалентный «<».
  • le меньше или равно оператору, эквивалентному «<=».
  • gt больше, чем оператор, эквивалентный «>».
  • ge больше или равно, эквивалентно « >=.

4.4. Оценка EL в поддерживающем компоненте

Из кода вспомогательного компонента можно оценить выражение EL с помощью приложения JSF. Это открывает целый мир возможностей при подключении страницы JSF к компоненту поддержки. Вы можете легко получить неявные объекты EL или фактические компоненты HTML-страницы или их значение из вспомогательного компонента:

FacesContext ctx = FacesContext.getCurrentInstance(); 
Application app = ctx.getApplication();
String firstName = app.evaluateExpressionGet(ctx, "#{firstName.value}", String.class);
HtmlInputText firstNameTextBox = app.evaluateExpressionGet(ctx, "#{firstName}", HtmlInputText.class);

Это дает разработчику большую гибкость при взаимодействии со страницей JSF.

5. Что нельзя делать в EL

EL < 3,0 имеет некоторые ограничения. В следующих разделах обсуждаются некоторые из них.

5.1. Нет перегрузки

EL не поддерживает использование перегрузки. Итак, в резервном компоненте со следующими методами:

public void save(User theUser);
public void save(String username);
public void save(Integer uid);

JSF EL не сможет правильно оценить следующее выражение

<h:commandButton value="Save" action="#{ELBean.save(firstName.value)}"/>

JSF ELResolver проанализирует определение класса bean и выберет первый метод, возвращаемый java.lang.Class#getMethods (метод, который возвращает методы, доступные в классе). Порядок возвращаемых методов не гарантируется, и это неизбежно приведет к неопределенному поведению.

5.2. Никаких перечислений или постоянных значений

JSF EL < 3.0 не поддерживает использование постоянных значений или перечислений в скрипте. Таким образом, имея любой из следующих

public static final String USER_ERROR_MESS = "No, you can’t do that";
enum Days { Sat, Sun, Mon, Tue, Wed, Thu, Fri };

означает, что вы не сможете сделать следующее

<h:outputText id="message" value="#{ELBean.USER_ERROR_MESS}"/>
<h:commandButton id="saveButton" value="save" rendered="bean.offDay==Days.Sun"/>

5.3. Нет встроенной нулевой безопасности

JSF EL < v3.0 не обеспечивает неявный нулевой безопасный доступ, что некоторым может показаться странным в современном механизме сценариев.

Так что, если человек в приведенном ниже выражении равен нулю, все выражение терпит неудачу с неприглядным NPE.

Hello Mr, #{ELBean.person.surname}"

6. Заключение

Мы рассмотрели некоторые основы JSF EL, сильные стороны и ограничения.

Это в значительной степени универсальный язык сценариев с некоторыми возможностями для улучшения; это также клей, который связывает представление JSF с моделью и контроллером JSF.

Исходный код, сопровождающий эту статью, доступен на GitHub .