ISSN 0236-235X (P)
ISSN 2311-2735 (E)

Journal influence

Higher Attestation Commission (VAK) - К1 quartile
Russian Science Citation Index (RSCI)

Bookmark

Next issue

4
Publication date:
09 December 2024

Implementation details of an architectural pattern Thin web client on Java EE 6 platform

The article was published in issue no. № 2, 2010
Abstract:Article describes implementation example of creation full-featured application interface based on a Thin Web Client pattern, using the Java Server Faces framework. To build the user interface used Woodstock JSF-components, extended with the DynamicFaces library.
Аннотация:На конкретном примере рассматривается технология создания полнофункционального интерфейса web-прило-жения на основе шаблона Thin web client с помощью фреймворка Java Server Faces. Для построения пользовательского интерфейса применяются JSF-компоненты Woodstock, расширенные с помощью библиотеки DynamicFaces.
Authors: Arzhaev V.I. (arzhaeVI@cps.tver.ru) - R&D Institute Centerprogramsystem (Branch Manager), Tver, Russia, Ph.D, (arzhaeVI@cps.tver.ru) -
Keywords: asynchronow Javascript and XML, framework Java Server Faces, DynamicFaces, architectural pattern of web-application
Page views: 12845
Print version
Full issue in PDF (4.97Mb)
Download the cover in PDF (1.38Мб)

Font size:       Font:

Архитектурный шаблон Thin web client (тонкий web-клиент) обычно используется в тех web-приложениях, в которых гарантируется наличие минимальной конфигурации клиента. При этом вся бизнес-логика выполняется на сервере в процессе обработки запроса на получение страницы, сгенерированного браузером клиента.

Термин расширенное клиентское приложение относится к настольным приложениям с расширенными возможностями, в то время как термин приложение для тонкого клиента относится к приложениям, базирующимся на архитектурных шаблонах web-приложений. Обычно расширенные клиенты сложны в развертывании и управлении, с другой стороны, тонкие клиенты не имеют таких широких возможностей пользовательского интерфейса и не так быстро реагируют, как толстые/рас­ширенные клиенты.

По мере развития технологий возникает новое поколение платформ и сред разработки для создания приложений для конечного пользователя. Асинхронный JavaScript и XML (AJAX), Rich Internet Application (RIA), Rich Client Platform (RCP) и Flash обеспечивают технологию, среду разработки и приемы, которые позволяют разработчикам создать web-приложения для конечного пользователя на основе шаблона тонкий клиент с гораздо более богатыми пользовательскими интерфейсами и повышенной быстротой реакции.

Для разработки web-приложений используются два подхода: на основе компилируемых модулей и интерпретируемых сценариев.

Наиболее популярным решением является Java Server Pages (JSP). Страницы JSP, хотя и содержат сценарии, при первом обращении к ним подлежат компиляции и загружаются как сервлеты. Пока серверная страница не изменяется, web-сервер продолжает использовать уже скомпилированный сервлет. Это дает некоторый выигрыш в производительности при использовании JSP по сравнению с другими типами сценариев. При разработке приложения на основе архитектуры тонкого клиента предлагается активно использовать достаточно новую компонентную, событийно-ориентированную технологию создания web-приложений Java Server Faces (JSF). Фактически подобно Swing и AWT приложение JSF – это каркас разработки приложений, предоставляющий набор стандартных графических компонентов для создания пользовательского интерфейса на стороне сервера.

Приложение, созданное на основе JSF, состоит из следующих частей:

-    объекты JavaBean, управляющие состоянием и поведением приложения;

-    компоненты GUI с возможностью сохранения состояния;

-    классы, реализующие событийную модель, аналогичные используемым при традиционной разработке графических интерфейсов;

-    страницы, выступающие в роли представлений (view) в парадигме модель-представление-контроллер (model-view-controller – MVC).

Кроме стандартных, JSF-компонентам доступны дополнительные компоненты, предоставляемые сторонними разработчиками.

JSF состоит из модели публикации событий; простого контейнера для зависимых компонентов (inversion-of-control (IoC) container); компонентов, реализующих практически все стандартные возможности графических интерфейсов: встраиваемую генерацию интерфейса, валидацию на стороне сервера, конвертирование данных, управление переходами (навигацией) между страницами.

Являясь компонентной архитектурой, JSF легко расширяется и конфигурируется. Интерфейс JSF-приложения состоит из страниц JSP, которые содержат компоненты, обеспечивающие функциональность интерфейса. JSF не имеет непосредственного отношения к JSP: данная технология лишь использует JSP через специальную библиотеку тегов – своего рода мост. Жизненный цикл компонент JSF сильно отличается от цикла JSP-страниц. При этом альтернативную технологию управления представлением Facelets гораздо легче использовать вместе с JSF, так как она изначально проектировалась под нужды JSF вместо интеграции JSF и JSP.

Однако страницы проходят все 6 стадий жизненного цикла JSF, на стороне сервера выполняются требуемые вызовы класса backing bean, который изменяет состояние компонентов и возвращает пользователю обновленную версию страницы. Это достаточно долгий путь для такого простого действия, ведь, чтобы обновить одно текстовое поле на странице, сервер приложения тратит свои ресурсы на ее полную перерисовку.

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

Такой интерфейс подходит для отображения статичес­кого содержимого, но если стоит задача активного взаимодействия с пользователем, построенные стандартным способом web-страницы перестают напоминать интерфейс настольного приложения.

Для решения этих задач разработчики web-приложений применяют технологию асинхронного обновления страниц – Asynchronous Javascript and XML (AJAX).

Важно то, что появилась возможность усилить данную технологию, поскольку желательно управлять всеми сложностями DOM, JavaScript и CSS-браузера. Таким образом, появляется новый класс web-приложений, предлагающих известное поведение толстого клиента, которое было преобладающим до того, как web стал популярным. Разработка web-приложений RIA (Rich Internet Appli­cation) предоставляет пользователю практику более живого взаимодействия, отсутствует необходимость полностью обновлять страницу для каждой транзакции. Самое важное в данном методе разработки web-приложения – рациональное использование клиентской стороны JavaScript и/или DHTML с применением асинхронного JavaScript и XML (AJAX) подхода. AJAX сам по себе предоставляет превосходную практику для конечного пользователя, но он основан в большей степени на трудоемком программировании на языке Java­Script. Однако в паре с JSF эта сложность существенно уменьшается посредством инкапсуляции сложного AJAX-JavaScript-кода в JSF-компонент­ную технологию. AJAX позволяет web-клиенту делать запросы к серверу асинхронно, независимо от представления всей страницы конечному пользователю.

Следовательно, в дополнение к значительному усовершенствованию пользовательского интерфейса AJAX совместно с JSF предусматривает более сложную событийную модель, в которой интерактивные действия основаны на особых UI-событиях в противовес упрощенным событиям HTTP GET и POST, когда вся страница обновляется полностью.

Применение в качестве сервера приложений GlassFish в составе программного обеспечения поддерживает использование специального расширения DynamicFaces для дополнения функциональности AJAX компонентам Java Server Faces. DynamicFaces обеспечивает дополнительную функциональность любому (не только созданному) компоненту UI, который используется при разработке JSF-приложения. При этом не требуется модифицировать компонент или переписывать фрагменты кода для придания приложению преимуществ технологии AJAX. Кроме того, в большинстве случаев даже нет необходимости прибегать к написанию JavaScript, поскольку Dynamic­Faces обеспечивает компоненты собственным набором библиотек JavaScript, реализующих AJAX. В то же время DynamicFaces сохраняет мощную компонентную модель и специфические стадии жизненного цикла, присущие уникальной технологии JavaServer Faces.

Рассмотрим основные элементы работы предлагаемого расширения DynamicFaces. Как указывалось ранее, цель применения AJAX состоит в том, чтобы обеспечить асинхронное обновление части страницы в ответ на события, инициируемые пользователем взамен ожидания перезагрузки страницы целиком.

DynamicFaces направлена на получение преимуществ такой функциональности компонентами JSF при поддержании сложной модели жизненного цикла «запрос–отклик» путем внедрения следующих элементов:

·     пользовательского JSP-тега, именуемого AjaxZone и используемого для идентификации той части дерева компонентов, которой добавляется функциональность AJAX;

·     набора функций JavaScript, придающих выбранным компонентам свойства AJAX, чтобы отправить AJAX-запрос серверу, обновить данные дерева элементов модели DOM на клиентском браузере после получения AJAX отклика от сервера (существует возможность использования некоторых из этих функций непосредственно в методах компонентов);

·     набора API, определяющих объекты со стороны сервера и вовлеченных в процесс обработки AJAX-запроса;

·     субдерева компонентов, требующих асинхронного обновления на стадиях жизненного цикла, конструирования и отправки AJAX-отклика клиенту.

Наиболее широко используемыми функциями JavaScript, включенными в DynamicFaces, являются:

·     fireAjaxTransaction – функция инициализирует AJAX-запрос с набором параметров, указывающим на компоненты асинхронного обновления;

·     Подпись:  Рис. 1. Группирование фаз жизненного цикла JSFinstallDeferredAjaxTransaction – сопоставляет fireAjaxTransaction с элементом DOM, требование fireAjaxTransaction задерживается, что означает вызов только в моменты инициируемых пользователем событий;

·     inspectElement – обращается к элементам, разграниченным тегом AjaxZone, и указывает на тот, который должен представить поведение в стиле AJAX, по умолчанию добавляется к элементам ввода и опциональным элементам.

Наиболее важными объектами на стороне сервера, участвующими в поддержке обработки AJAX-запроса, создании конструкции и обслуживании доставки AJAX-отклика, являются:

o    PartialTraversalViewRoot – реализация поль­зовательского ViewRoot, представляющего ту часть дерева компонентов, которая нуждается в асинхронной обработке;

o    PartialTraversalLifecycle – реализация пользовательского Lifecycle, которая сочетается с выполнением ViewRoot для возвращения соответствующего субдерева компонентов в требуемое время;

o    AsyncResponse – ссылается на сформатированное XML-сообщение, которое представляет частичное обновление дерева компонентов.

При использовании расширения DynamicFaces фазы жизненного цикла JSF группируются по функциональности (рис. 1).

Часть жизненного цикла (execute – исполнение) выполняется в течение так называемого процесса обработки (post­back) и включает те фазы жизненного цикла, которые обеспечивают преобразование данных, валидацию и обновление объекта модели приложения. Группа фаз обновления (render) возвращает результат выполнения запроса на странице.

Рассмотрим один из подходов к реализации асинхронной технологии. Чтобы начать использовать компонент DynamicFaces на странице, необходимо подключить дополнительно пространство имен: .

После чего на странице становятся доступными для использования теги и . Для асинхронного обновления компонентов страницы создадим Ajax-тран­закцию внутри тега : .

С помощью свойства inputs указываются компоненты, которые необходимо выполнить на сервере, а свойство render указывает элементы для обновления до завершения запроса. Созданную Ajax-транзакцию можно вызвать с помощью простого JavaScript-кода, который будет исполняться при нажатии на кнопку onClick="DynaFaces.Tx. fire('ajaxTransaction1')".

Кроме того, Ajax-транзакция вызывается с помощью события onSubmit для формы страницы. Событие произойдет, когда пользователь нажмет на клавишу ENTER. При этом функция onSubmit должна возвращать значение FALSE, чтобы предотвратить обновление страницы при подтверждении формы onSubmit="DynaFaces.Tx.fire('Ajax­Transaction1');returnfalse;".

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

Подпись:  
Рис. 2.  JSF страница web-приложенияПусть имеется страница, предназначенная для управления учетными записями пользователей. На ней расположены несколько вкладок, позволяющих управлять зарегистрированными в системе пользователями, группами пользователей и аккаунтами. Страница имеет вид, представленный на рисунке 2.

Для управления учетными записями пользователю необходимо переключаться между вкладками Пользователи, Аккаунты и Группы. При использовании обычных JSF-компонентов каждое переключение между вкладками заставляет сервер полностью перерисовывать страницу и обновлять все находящиеся на ней компоненты.

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

Приведем исходный код страницы без использования асинхронной обработки запроса:

<f:subview id="usersFragment"> <!-- Панель навигации --> <div id="centralFragmentHeader"> <webuijsf:breadcrumbs id="mainBreadcrumbs6" styleClass="breadcrumbs"> <webuijsf:hyperlink id="hyperlink1" text="Главное меню" url="/faces/ mainPage.jsp"/> <webuijsf:hyperlink id="hyperlink2" text="Администрирование" url="/faces/adminPage.jsp"/> <webuijsf:hyperlink id="hyperlink3" text="Управление пользователями" url="/faces/adminPage.jsp?taskId=2"/> <webuijsf:hyperlink id="hyperlink4" text="Пользовательские аккаунты" url="/faces/adminPage.jsp?taskId=2"/> </webuijsf:breadcrumbs> <!--Серая горизонтальная полоса--> <hr noshade="true"/> </div> <!-- Панель с закладками (Пользователи, Аккаунты, Группы)--> <webuijsf:tabSet id="usersTabSet" mini="true" selected="usersTab"> <webuijsf:tab id="usersTab"  styleClass="MniTabLnk_sun4" text="Пользователи"> <!--Содержимое вкладки "Пользователи" --> <webuijsf:panelLayout id= ="usersTabPanel" panelLayout="flow" style= ="padding-left: 10px; margin-top: 20px;"> <!--Фрагмент с возможностью просмотра и редактирования пользователей--> <jsp:directive.include file="usersFragments/userInfo.jspf"/> </webuijsf:panelLayout> </webuijsf:tab> <webuijsf:tab id="accountsTab" text="Аккаунты"> <!-- Содержимое вкладки "Аккаунты" --> <webuijsf:panelLayout id="accountsTabPanel" panelLayout="flow" style="width: 100%; height: 128px;"> <jsp:directive.include file="usersFragments/accountInfo.jspf"/> </webuijsf:panelLayout> </webuijsf:tab> <webuijsf:tab id="groupsTab" text="Группы"> <!--Содержимое вкладки "Группы"--> <webuijsf:panelLayout id="groupsTabPanel" panelLayout="flow" style="width: 100%; height: 128px;"> <jsp:directive.include file="usersFragments/groupInfo.jspf"/> </webuijsf:panelLayout> </webuijsf:tab> </webuijsf:tabSet> <!-- Конец фрагмента--> </f:subview>          

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

1. Подключить пространство имен, чтобы иметь возможность использовать теги Dynamic­Faces на странице xmlns:df=http://java.sun.com/jsf/ dynamicfaces.

2. Определить внутри страницы Ajax-транзак­ции для обновления каждой вкладки:

3) Связать компонент tabSet со свойством прикрепленного к странице класса:

Для изменения своего состояния компонент tabSet передает новые параметры с помощью GET-запроса к странице, на которой находится. Так как для этого потребуется перезагрузка страницы в браузере, что неприемлемо, сделаем небольшое изменение. К каждой вкладке компонента tabSet, описываемой при помощи тега , добавим событие onClick, по которому будет запускаться соответствующая Ajax-транзакция: «renderTab1» – для первой вкладки, «renderTab2» – для второй и так далее для последующих.

Пример добавления события для вкладки «Пользователи»:

Нетрудно заметить, что при определении транзакций перечисленные в свойстве input идентификаторы компонентов не совпадают с теми, что присвоены вкладкам компонента tabSet. Это сделано потому, что при попытке вызвать код, установленный свойством actionExpression для вкладок, ничего не произойдет, так как при нажатии на вкладку страницы компонент пытается обновить свое состояние с помощью передачи на текущую страницу GET-запроса. Это вызовет неминуемую перезагрузку страницы, поэтому компонент вынесен за пределы тега

, в результате он срабатывает вхолостую.

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

С каждой из созданных кнопок агрегирован код следующего вида:

    public String tab3_action() {

      usersTabSet.setSelected("groupsTab");

      return null;

    }

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

Заново построим пример и развернем на сервере приложений.

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

Приведем фрагмент кода страницы, полученной в результате добавления к компонентам JSF Ajax-функциональности:

 Подводя итоги реализации web-приложения на основе платформы Java EE 6 с использованием JSF и DynamicFaces, можно утверждать, что технология JSF с расширением DynamicFaces позволяет создавать web-приложения, функционально не отличающиеся от своих настольных аналогов, увеличить скорость работы web-приложения, сократив тем самым время реакции за счет группирования фаз жизненного цикла компонентов и их точечного обновления, а также снизить нагрузку на сервер приложений, заставляя его обновлять отдельные компоненты интерфейса вместо целых страниц.

Литература

1. Создание корпоративных систем на основе Java 2 Enterprise Edition. Руководство разработчика; пер. с англ. М.: Издат. дом «Вильямс», 2001. 1184 с.

2. Jonas J. Pro JSF and Ajax. Building Rich Internet Components / Jonas Jacobi, John R. Fallows. Изд-во «Apress», 2006.


Permanent link:
http://swsys.ru/index.php?id=2525&lang=en&page=article
Print version
Full issue in PDF (4.97Mb)
Download the cover in PDF (1.38Мб)
The article was published in issue no. № 2, 2010

Perhaps, you might be interested in the following articles of similar topics: