Spring Web Flow — язык выражений (EL — expression language)

4. Язык выражений

4.1 Введение

Web Flow использует EL (expression language) для доступа к модели данных и вызова действий. В этой главе вы познакомитесь с синтаксисом EL, конфигурацией и специальными EL переменными, которые вы можете получить из описания вашего потока.

EL используется для многих вещей внутри потока, включая:

  1. Доступ к клиентским данным, таким как объявленным входным данным (элемент input) потока или ссылкам к параметрам запроса (request parameters).
  2. Доступ к данным в RequestContext Web Flow таким как flowScope или currentEvent.
  3. Вызов методов объектов, управляемых Spring, с помощью действий (actions).
  4. Вычисление выражений таких как переходы, ID подпотоков и имена представлений.

EL так же используется для связки параметров к модели объектов и обратно, чтобы отрисовать форматированные поля формы из свойств объекта модели. Однако это не работает при использовании Web Flow и JSF, т.к. в этом случае применяется стандартный жизненный цикл компонентов JSF.

4.1.1 Типы выражений

Важно понять, что есть два типа выражений в Web Flow: стандартные выражения и шаблонные.

Стандартные выражения

Первое и наиболее часто используемое выражение — стандартное выражение. Выражения такого типа вычисляются  непосредственно EL и не должны быть заключены в #{}. Например:

Выражение сверху является стандартным выражением, которое вызывает метод nextPage() переменной searchCriteria. Если вы попытаетесь вложить это выражение в #{}, то получите IllegalArgumentException. В этом контексте разделитель {} рассматривается как излишний. Допустимым значением выражения expression является простая строка.

Шаблонные выражения

Второй тип выражений — шаблонные выражения. Шаблонные выражения позволяют смешивать текст с одним или более стандартным выражением. Каждый блок с стандартным выражением заключается в разделитель #{}. Пример:

Выражение выше — шаблонное выражение. Результат вычисления будет конкатенацией строк error- и .xhtml с результатом вычислинным в externalContext.locale. Как вы можете видеть разделители необходимы для отделения вычисляемого выражения от шаблона.

4.2. EL реализации

4.2.1 Spring EL

Начиная с версии 2.1 Web Flow использует Spring Expression Language (Spring EL). SpEL был создан для обеспечения единого, четко поддерживаемого языка выражений для всех продуктов Spring. Он поставляется как отдельный jar org.springframework.expression в Spring Framework. В уже существующих приложениях необходимо удалить зависимости org.jboss.el или org.ognl и использовать взамен org.springframework.expression. О переносимости читайте ниже.

4.2.1 Unified EL

В Web Flow 2.0 Unified EL был основным языком выражения с реализаций jboss-el. Использование Unified EL предполагает реализацию зависимости el-api, которая обычно предоставляется веб-контейнером (например Tomcat 6). SpEL теперь является языком выражений по умолчанию и рекомендуется к использованию. Однако существует возможность заменить его на Unified EL, если возникнет такая необходимость. Для этого необходимо подключить к конфигурации Spring WebFlowELExpressionParser в flow-builder-services:

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

4.2.3 OGNL

Указан как устаревший в Web Flow 2.4.

4.3. Переносимость EL

В общем, вы обнаружите, что SpEL, Unified EL и OGNL имеют очень похожий синтаксис.

Вот несколько небольших изменений, которые необходимо знать для перехода на Spring EL от Unified EL или OGNL:

  1. ${} меняется на #{}.
  2. Выражения тестирующие данное событие #{currentEvent == ‘submit’} должно быть изменено на  #{currentEvent.id == ‘submit’}
  3. Вычисление свойств вроде #{currentUser.name} может вызвать NullPointerException без проверок вроде #{currentUser != null ? currentUser.name : null}. Поэтому лучше использовать такую безопасную запись #{currentUser?.name}.

Для более подробной информации о синтаксисе SpEL смотрите Language Reference.

4.4. Специальные переменные EL

Есть несколько неявных переменных, на которые вы можете ссылаться из потока. Эти переменные будут рассмотрены в этом разделе.

Имейте в виду это общее правило. Переменные относящиеся к области данных (flowScope, viewScope, requestScope, etc.) должны использоваться только при назначении новых переменных области видимости.

Например, при присвоении результата вызова метода bookingService.findHotels(searchCriteria) в новую переменную «hotels«, вы должны использовать префикс области видимости для того, чтобы Web Flow мог понять где ее хранить:

Однако при установке в существующую переменную, такую как «searchCriteria» из примера ниже, вы ссылаетесь прямо на переменную без префикса какой-либо области видимости:

Ниже приведен список неявных переменных, на которые вы можете ссылаться из потока:

4.4.1 flowScope

Используйте flowScope для назначения переменной потока. Переменная выделяется при старте потока и уничтожается при его завершении. С реализацией по умолчанию, любой объект в этой переменной должен быть сериализован.

4.4.2 viewScope

Используйте viewScope для назначения переменной в области отображения. Переменная выделяется при входе в view-state и уничтожается при выходе. Переменная viewScope доступна только из конкретного view-state. С реализацией по умолчанию, любой объект в этой переменной должен быть сериализован.

4.4.3 requestScope

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

4.4.4 flashScope

Используйте flashScope для кратковременных переменных. Выделяется при старте потока, очищается при каждом рендере и уничтожается при завершении потока. С реализацией по умолчанию, любой объект в этой переменной должен быть сериализован.

4.4.5 conversationScope

Данная переменная выделяется при старте родительского потока и уничтожается когда при его завершении. Conversation scope доступна для родительского потока и всех его подпотоков. Согласно реализации по умолчанию, объекты conversation scope сохраняются в HTTP сессии и должны быть сереализованы для конкретной сессии.

4.4.6 requestParameters

Используйте requestParameters для хранения параметров запросов клиента:

4.4.7 currentEvent

Используйте currentEvent для доступа к атрибутам текущего события

4.4.8 currentUser

currentUser используйте для доступа к прошедшему проверку Principal:

4.4.9 messageContext

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

4.4.10 resourceBundle

Используйте для доступа к message resource.

4.4.11 flowRequestContext

Используйте flowRequestContext для доступа к RequestContext API, который представляет текущий запрос потока.

4.4.12 flowExecutionContext

Используйте flowExecutionContext для доступа к FlowExecutionContext API, который представляет текущее состояние потока.

4.4.13 flowExecutionUrl

Используйте flowExecutionUrl для доступа к текущему относительному URI для данного состояния view-state потока.

4.4.14 externalContext

Используйте externalContext для доступа к клиентской стороне, включая атрибуты сессии пользователя.

4.5 Алгоритм поиска «Scope»

Как уже упоминалось ранее, при определении переменной потока, необходимо указывать область видимости. Пример:

При простом доступе к переменной в одной области видимости, указание области видимости не обязательно. Пример:

Когда область видимости не определена, как в случае booking выше, то используется алгоритм поиска области видимости. Алгоритм просматривает соответственно: request, flash, view, flow, а также conversation. Если ничего не найдено, то будет выброшено исключение EvaluationException.

Share Button
0
6023 Total Views 4 Views Today

Добавить комментарий