Статьи

Реализация навигации и потоков страниц с помощью шва

Seam — это интересный веб-фреймворк, объединяющий различные части стека приложений и включающий идеи из механизмов правил, BPM и SOA в обычную разработку приложений. В этой статье основное внимание уделяется навигации в Seam и функциям, связанным с потоком. Посмотрим, как они могут разыграть на практике.

Статья логически делит тему на две части, которые сопоставляются с двумя моделями навигации, а именно без сохранения состояния и с сохранением состояния. В Seam реализация без сохранения состояния использует потоки страниц в стиле JSF, в то время как реализация с состоянием использует потоки страниц jPDL.

Навигационные модели

Переход от страницы к странице или просмотр для просмотра в веб-приложении может зависеть от состояния приложения или зависеть от него. Другими словами, это может быть без гражданства или с состоянием. В модели без состояния набор правил отображает действия или результаты событий на конкретные виды или страницы. Напротив, в модели с сохранением состояния правила навигации определяют переходы из одного состояния в другое, что в процессе приводит к переходу из одного представления или страницы в другое. Вы можете спросить, почему модели навигации вообще должны быть с состоянием, а также спросить, как информация о состоянии может быть связана с правилами навигации. Оба вопроса актуальны и важны, поэтому я постараюсь ответить на них прямо сейчас.

В управляемом процессом веб-приложении поток от одной страницы к другой часто регулируется состоянием приложения и задачами решения, которые используют эту информацию о состоянии. В качестве примера рассмотрим приложение для обработки кредита, которое проявляется как веб-приложение. В этом приложении пользователь может быть переведен со «страницы приветствия» на «страницу сбора информации о кредите» или «страницу изменения и подтверждения информации». Выбор страницы для перехода будет зависеть от того, является ли заявитель действующим утвержденным клиентом или нет. Существующий клиент будет отправлен на «страницу изменения и подтверждения информации», поскольку большая часть информации, относящейся к обработке кредита, уже доступна, а новый клиент будет перенаправлен на «страницу сбора информации о кредите», так как основная информация должна быть доступна до любые дальнейшие решения могут быть приняты.Предположим, что такое приложение также дает пользователю возможность обновить свой статус утверждения. Например, конкретный пользователь может быть одобрен для получения кредита на сумму до 500 000 долларов США, но теперь ему необходимо увеличить сумму утверждения кредита до 1 миллиона долларов США. В этом примере на странице «Изменение и подтверждение информации» пользователь решит обновить сумму кредита и будет перенаправлен на «страницу получения дополнительной информации». Вы видите, что здесь происходит, навигация по существу отражает жизнеспособные переходы, которые зависят от текущего состояния приложения. Это сценарий перехода состояния, вот и все! Этот поток изображен на рисунке под названием: «Процесс обработки заявки на получение кредита».000, но теперь необходимо обновить сумму одобрения кредита до 1 миллиона долларов. В этом примере на странице «Изменение и подтверждение информации» пользователь решит обновить сумму кредита и будет перенаправлен на «страницу получения дополнительной информации». Вы видите, что здесь происходит, навигация по существу отражает жизнеспособные переходы, которые зависят от текущего состояния приложения. Это сценарий перехода состояния, вот и все! Этот поток изображен на рисунке под названием: «Процесс обработки заявки на получение кредита».000, но теперь необходимо обновить сумму одобрения кредита до 1 миллиона долларов. В этом примере на странице «Изменение и подтверждение информации» пользователь решит обновить сумму кредита и будет перенаправлен на «страницу получения дополнительной информации». Вы видите, что здесь происходит, навигация по существу отражает жизнеспособные переходы, которые зависят от текущего состояния приложения. Это сценарий перехода состояния, вот и все! Этот поток изображен на рисунке под названием: «Процесс обработки заявки на получение кредита».навигация по существу отражает жизнеспособные переходы, которые зависят от текущего состояния приложения. Это сценарий перехода состояния, вот и все! Этот поток изображен на рисунке под названием: «Процесс обработки заявки на получение кредита».навигация по существу отражает жизнеспособные переходы, которые зависят от текущего состояния приложения. Это сценарий перехода состояния, вот и все! Этот поток изображен на рисунке под названием: «Процесс обработки заявки на получение кредита».

 

 

Рисунок 1: процесс подачи заявки на утверждение кредита

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

Далее давайте рассмотрим вопрос о том, как можно реализовать правила навигации с отслеживанием состояния. Это просто и есть много способов сделать это. Нам нужен механизм для определения процесса и способ перевода этого описания процесса в исполняемый код. Сегодня доступно множество языков определения процессов, которые могут с легкостью описать процесс. jPDL, BPEL и XPDL являются примерами языков описания процессов на основе XML. Они определяют теги, которые описывают задачи, состояния и решения и позволяют процессам разворачиваться и присоединяться. Конечно, между этими языками описания процессов существуют различия в терминах конкретных имен тегов и полного словаря этих тегов. Механизмы рабочих процессов могут выполнять процесс, определенный на одном или многих из таких языков. описания процессов jPDL могут быть успешно выполнены jBPM,механизм управления рабочими процессами и бизнес-процессами JBoss. Шов интегрируется с jPDL и использует jBPM для выполнения описанного процесса. Вам не нужно быть экспертом в jPDL или jBPM, чтобы использовать Seam, и вы можете пропустить все это средство, если вам вообще не нужны потоки страниц с отслеживанием состояния. Тем не менее, Seam предоставляет простой и понятный способ реализации потоковых страниц с отслеживанием состояния, и вы получите большую пользу от знакомства с этой опцией.

Потоки страниц в стиле JSF

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

Поскольку Seam изначально создавался для устранения разрыва между EJB3 и JSF и интеграции интегрированных сред JEE, его модель пользовательского интерфейса по умолчанию использует JSF. Фактически, это улучшает и расширяет возможности JSF во многих областях, включая определение навигации. В последней версии 2.0.2 RC2 каркас не связан с моделью JSF. Процесс развязки был начат пару ревизий назад. Если Seam используется без какой-либо JSF, все равно можно определить навигацию без сохранения состояния с одной страницы на другую, используя функции, которые мы скоро опишем.

Модель навигации без сохранения состояния по определению не знает о состоянии приложения при переходе с одной страницы на другую. Он опирается на отображение страниц на события или результаты действий. Думайте об этом как о предложении переключения регистра, где конкретная ветвь, которая должна быть выполнена, определяется значением регистра, которому она соответствует. Принятие решения без сохранения состояния в элементарных ситуациях можно сравнить с раздвоением потока на основе логического свойства, которое может быть либо истинным, либо ложным. Решение основывается только на стоимости дела и не зависит от состояния приложения. Обработчик действия или события может генерировать результат на основе состояния приложения, но это выходит за рамки правил навигации. То, что заботит правило навигации, является результатом, а не тем, как результат получен.

В JSF правила навигации без сохранения состояния определяются в файле Face-config.xml. Список (номер 1) ниже показывает пример определения навигации JSF. Эту стратегию можно использовать с Seam, поскольку Seam поддерживает JSF.

Listing 1: Example JSF navigation definition
<navigation-rule>
<from-view-id>fromStartPage.jsp</from-view-id>
<navigation-case>
<from-outcome>goAhead</from-outcome>
<to-view-id>toNextPage.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>stopNow</from-outcome>
<to-view-id>byeNow.jsp</to-view-id>
</navigation-case>
</navigation-rule>

 

JSF не определяет действие страницы. Это означает, что JSF не вызывает ничего особенного после рендеринга страницы. Никакие действия не активированы или события срабатывают. Шов определяет действия страницы. Действия страницы и связанные с ними функции можно использовать для определения потоков страниц без сохранения состояния и выходить за рамки модели потока страниц JSF. Действия страницы определяются в файле конфигурации с именем pages.xml. Таким образом, с помощью Seam, если бы кто-то использовал навигацию JSF и потоки страниц одновременно, можно было бы использовать два файла конфигурации для управления правилами навигации. Это были бы лица-config.xml и pages.xml. Однако нет необходимости использовать обе опции одновременно. Все, что может быть сделано с использованием модели навигации JSF, может быть выполнено в файле pages.xml, поэтому целесообразно объединить все прямо там.

Перечисление 2-4 показывает фрагменты из файла pages.xml, чтобы проиллюстрировать функции навигации без сохранения состояния. Пример приложения в этих списках — это система ведения блогов, которая помогает вам создавать новую запись, редактировать существующую запись, просматривать ее и публиковать. Это также позволяет вам принимать и отвечать на комментарии к этим записям. На рисунке 2 в графическом виде изображены страницы приложения и функции, относящиеся к созданию блога.

 

Рисунок 2: Поток в системе создания блогов

 

Наш первый листинг в этом наборе, т. Е. Листинг 2, представляет собой только начальную бифуркацию между созданием нового документа и редактированием существующего документа на основе существования документа. В листинге 3 показан поток по новому пути ввода, а в листинге 4 показан поток по пути, в котором мы редактируем существующий документ.

Listing 2:  Seam navigation that either redirects to 
new document creation or editing of an existing one
<page view-id="welcome.xhtml">
<navigation from-action="#{documentToManipulate.exists}">
<rule if-outcome="true">
<redirect view-id="editDocument.xhtml"/>
</rule>
<rule if-outcome="false">
<redirect view-id="createDocument.xhtml"/>
</rule>
</navigation>
</page>

Вы заметили, что в листинге 2 вызывается метод с именем documentToManipulate (). Этот метод возвращает возвращаемое значение логического типа. Таким образом, возвращаемое значение может быть истинным или ложным.

 

 

In Listing 3, which shows navigation for a new document creation, you will notice a separate view for the action that saves a document. In real situations you may not desire a separate view to come up on saving a document to say that the document has been saved. It would be implicit.

Listing 3: Navigation that defines the flow for creation of a new document
<page view-id="createDocument.xhtml">
<navigation from-action="#{documentManager.preview}">
<rule if-outcome="#{documentManager.preview.assetTrue}">
<redirect view-id="previewDocument.xhtml"/>
</rule>
</navigation>
<navigation from-action="#{documentManager.readyTosave}">
<rule if-outcome="yes">
<redirect view-id="saveDocument.xhtml"/>
</rule>
</page>
<page view-id="previewDocument.xhtml">
<navigation from-action="#{documentManager.creationComplete}">
<rule if-outcome="success">
<redirect view-id="publishDocument.xhtml"/>
</rule>
<rule if-outcome="failure">
<redirect view-id="editDocument.xhtml"/>
</navigation>
</page>

Continuing with Listing 4, we see the navigation rule definition for flow around editing an existing blog entry. Only two actions, i.e. preview and save, are allowed for a blog being edited. The rule here only includes the flow to the preview page. You will notice that it is identical to the rule we define for preview in a new blog entry flow.

 

Listing 4:  Navigation that defines the flow for editing an existing blog entry
<page view-id="editDocument.xhtml">
<navigation from-action="#{documentManager.preview}">
<rule if-outcome="#{documentManager.preview.assetTrue}">
<redirect view-id="previewDocument.xhtml"/>
</rule>
</navigation>
</page>

The last of the listings in this set, i.e. Listing 5, is a hypothetical definition which tries to depict the extra features that Seam allows within the navigation rule definition in pages.xml. Some of the most important of these features relate to beginning and ending conversation during navigation and passing a request parameter during redirect. We have seen method evaluation outcomes as values for an action so far. Another interesting enhancement that Seam brings to navigation is to allow arbitrary EL expression outcomes to be values of an action.

Listing 5: Additional Seam specific navigation features
<page view-id="previewDocument.xhtml">
<navigation from-action="#{documentManager.creationComplete}">
<rule if-outcome="success">
<redirect view-id="publishDocument.xhtml"/>
<end-conversation />
</rule>
<rule if-outcome="failure">
<redirect view-id="editDocument.xhtml">
<param name=”blogId” value=”#{documentManager.blogId}”/>
</redirect>
</navigation>
</page>

The stateless navigation as mentioned before is the most popular model in use. Seam’s features are adequate and flexible to implement these use cases effectively. However, with workflow and business process management application rising in number and highly interactive applications gaining in popularity, the stateful model is becoming equally important. While many options exist to manage stateful transitions, Seam is leading the way in integrating such constructs within web application frameworks.

jPDL pageflows

jPDL is the process description language you will use to describe a process or a stateful pageflow within Seam. To get a flavor of the syntax and see it working in real life we will use an example. We will select an example where state transitions form the basis of all interactions. Our example is an online interactive game that involves two players where each player plays the alternate move. The outcome can be either one of the players winning or the game ending in a deadlock. Games like chess, tic-tac-toe, nim, dots and checkers fit into this type of interaction model. The source code for download implements the game of tic-tac-toe but it could equally well apply to any of the others on the list. Figure 3 shows the state transitions in such a game.

 

 

Figure 3: State transitions in a two player game where either one of them wins or the game ends in a draw

The states are start, make a move, victory or impasse. Alternate moves continue till either one wins or a stalemate is reached. Such a flow can be written very effectively using jPDL. Listing 6 illustrates the state transitions for our example application using jPDL.

Listing 6 jPDL shows state transitions for a two player game where each player plays alternatively and either one wins or the game ends in a draw. This is a very elementary example as compared to what one may encounter in real business situations. However, it gives a flavor of process definition and state transitions in a stateful flow scenario.

Listing 6: Process definition of the two player game
<process-definition name="twoPlayerGame" initial="start>
<state name="start">
<transition name="AStartsGame" to="APlays">
<transition name="BStartsGame" to="BPlays">
</state>

<state name="APlays">
<transition name="gameActive" to="BPlays">
<transition name="victory" to="AWins">
<transition name="impasse" to="draw">
</state>

<state name="BPlays">
<transition name="gameActive" to="APlays">
<transition name="victory" to="BWins">
<transition name="impasse" to="draw">
</state>
</process-definition>

The state transitions of this type could be implemented using Java within the action or event handler code. However, doing that would be neither easier nor as flexible. jPDL state transition changes can be made easily at one place in an XML file that resembles the natural language syntax. Changes to the code that manages state transitions in far more complicated and often not as decoupled. Also because it involves changes to the code rather than to a process description, it has to be done by a programmer. A person who has never programmed can also make changes to the XML file, since they are easy to understand.

Summary

This article was about showing the implementation strategies as they are leveraged in practice. Now that the basics are well understood its time to start picking up complex cases and determine which option to choose to define navigation. Making a decision between stateless and stateful models is not always clear and straightforward. Experience above all usually helps make this decision effectively.

Understanding navigation models means getting a sense of the dynamics of interaction and flow control under varied scenarios. Once the interaction strategies are well understood it’s easier to deal with the user interface elements themselves and see how the interaction impacts their behavior and presentation logic. In the case of rich interactions as with AJAX and RIA, the navigation models not only pervade across layers but include multiple languages and sometimes an additional client side framework with Seam.

Therefore getting hold of the navigation model early on is going to help you go a long way in building a robust and scalable web application.