Упростите интеграцию Ajax и Java EE

Сочетайте модели синхронной и асинхронной передачи данных

С ростом популярности Ajax наступает необходимость развеять мифы относительно этого, пользующегося большим спросом, продукта, и разобраться со всеми проблемами, которые могут возникнуть во время его использования.

Патрик Гэн, старший IT-специалист, Центр Инноваций Сервисов Приложений, IBM

Фото   Патрика ГэнаПатрик Гэн (Patrick Gan) – старший IT специалист в IBM Global Services. Область компетенции: Java EE, разработка объекнто-ориентированных приложений и использование систем с открытым кодом. В первую очередь Патрик принимает участие во встречах с клиентами и помогает им в фазах дизайна и разработки приложений Java EE. Также он работает над дизайном, разработкой и поддержкой Java EE систем для IBM. Он имеет степень по вычислительной технике и работает в IBM в течение шести лет.



08.05.2007

Ajax – это довольно новое понятие (хотя некоторые говорят, что это старая технология в новом обличии), которое наделало много шума в различных сообществах веб-разработчиков, включая Java EE. Технология Ajax делает работу в приложениями более удобной, устраняя необходимость бесчисленных обновлений веб-страниц. И кроме того, Ajax сближает серверную и клиентскую части кода и предоставляет веб-пользователю практически монолитный интерфейс. Ajax позиционируется как один из главных инструментов, который поможет интернету подняться на новый уровень (Web 2.0).

Как прилежные Java EE разработчики, вы вероятно читали многочисленные статьи с практическими рекомендациями по использованию Ajax, и, возможно, вас взволновало то, какие, благодаря нему, можно внести усовершенствования в ваши работы. Но каким же все-таки образом модель асинхронной передачи данных впишется в ваши Java EE приложения? Эта статья поможет вам найти ответ на этот вопрос, исследуя воздействие Ajax на дизайн, развитие, тестирование и работу Java EE приложений. Моя цель состоит не в том, чтобы препятствовать использованию технологии Ajax или намекать, что проблемы, с которыми вы можете столкнуться, свойственны технологии Ajax, а, скорее, в том, чтобы помочь вам все спланировать и упростить, и сделать вашу работу с Ajax более эффективной и приятной.

Недостатки схемы адресации

В течение достаточно длительного времени Java-сообщество усердно применяло шаблоны дизайна для веб-ориентированной разработки приложений. Одним из наиболее используемых является шаблон Модель-Вид-Контроллер (Model-View-Controller – MVC). Несколько архитектур с открытым кодом таких, как Apache Struts, основаны на этом дизайне – шаблон/архитектура (см. Ресурсы). Достоинства MVC включают в себя разделение ответственности и уменьшение количества избыточного кода.

Разделение ответственности позволяет каждому разработчику сфокусироваться на конкретной роли в заданном проекте приложения при помощи использования заранее оговоренных интерфейсов. Например, model-разработчики сосредотачиваются на таких технологиях, как JDBC, компонентах Enterprise JavaBeans (EJB) или Java-классах, которые взаимодействуют с основными data-persistence технологиями. View-разработчики сосредотачиваются на технологии JavaServer Pages (JSP), библиотеках тегов и других, связанных с презентациями, технологиях. Controller-уровень отделяет model-уровень от view и, одновременно, является связующим звеном между ними, сохраняя четкое разделение ответственности. Рисунок 1 иллюстрирует архитектуру MVC:

Рисунок 1. Архитектура MVC
Архитектура MVC

Внедрение Ajax в веб-приложения Java EE имеет значение при разделении ответственности (а потому и при разделении ролей разработчиков). В некоторых случаях Ajax может вывести большое количество JavaScript-кода обратно на страницу view-уровня (JSP). Таблица 1 демонстрирует view-уровень MVC без Ajax и показывает количество необходимого кода, в предположении, что controller-уровень представлен сервлетами, а view-уровень – технологией JSP. (Я объясню различие между синхронными и асинхронными запросами в следующем разделе Решение дилемм разработки.)

Таблица 1. MVC без Ajax: Количество кода, связанного с типичной последовательностью view-уровня
ПоследовательностьОписаниеТребуется код?
Перед вызовом синхронного запросаКод скриплета требуется при подготовке к отправке формы.Нет.
Вызов синхронного запросаОтправка формы инициализируется нажатием кнопки или ссылки; значения элемента DOM автоматически переводятся в HttpRequest (посредством GET или POST).Нет: все, что требуется – это способ инициализации отправки формы.
Прием ответа на синхронный запросПосле завершения обработки программой-сервером, обычно, объект отсылается обратно в JSP (через HttpRequest или сохраненным вHttpSession). На этом этапе объект доступен в JSP посредством использования HttpRequest или HttpSession (с помощью скриплета или какой-либо библиотеки тегов), и требуются минимальные усилия по созданию скриптов для отображения содержимого объекта.Да: минимум скриплетов.

Сравним Таблицу 1 с Таблицей 2, которая описывает view-уровень MVC с Ajax, так же предполагая, что controller-уровень представлен сервлетами, а view-уровень – технологией JSP.

Таблица 2. MVC с Ajax: Количество кода, связанного с типичной последовательностью view-уровня
ПоследовательностьОписаниеТребуется код?
Перед вызовом асинхронного запросаКод JavaScript требуется для получения значений DOM элементов, необходимых для вызова Ajax.Да
Вызов асинхронного запросаКод JavaScript требуется для создания XMLHTTPRequest и связи (заранее собранной) значений элементов DOM и отправки (XMLHTTPRequest.send()).Да
Прием ответа на асинхронный запросПосле завершения обработки программой-сервером код JavaScript требуется для получения результатов (из потока ответов в XML) и передачи значений в соответствии с определенными значениями элементов DOM.Да

Вы можете видеть, что количество скриптов в view-уровне увеличивается при использовании Ajax, что влечет за собой три существенных недостатка:

  • JSP требует большего количества кода JavaScript.
  • Дизайн нарушает разделение ответственности.
  • Дизайн повторно вводит монолитные JSP (Модель 1: море HTML-кода, CSS-кода, изображений и скриптов), антимодель, которая чрезвычайно неудобна для понимания и обслуживания (см. Ресурсы).

У вас есть несколько вариантов для избежания или, хотя бы, смягчения этих недостатков дизайна:

  • Дизайн с повторным использованием: К сожалению, часто трудно избежать скриптов, характерных для поддержки Ajax. Планируйте и проектируйте код скриптов так, чтобы добиться его максимального повторного использования.
  • Используйте клиентскую часть MVC: вы можете включить использование клиентской части MVC, этот способ подробно описан в статье Ajax в действии Дэйва Крэйна и др. (см. Ресурсы). Такой подход позволяет применить разделение ответственности, но добавляет проблем, поэтому стоит осмотрительно использовать его.
  • Используйте структуры Ajax: несколько структур Ajax таких, как Direct Web Remoting (DWR) (см. Ресурсы), помогают внедрить шаблон Ajax в приложение Java EE, используя минимальное количество кода.
  • Пересмотрите обоснованность проектирования: По существу, Ajax обеспечивает веб-приложения настольными атрибутами. Если большая часть клиентских взаимодействий в данном веб-приложении поддерживают Ajax, то, возможно, стоит сделать его в виде настольного приложения.

Решение дилемм разработки

Когда вы используете Ajax в разработке сетевых Java-приложений, важно полностью осознавать разницу между синхронной и асинхронной коммуникационными моделями (см. Ресурсы). Недостаток обеспечения асинхронной коммуникационной модели может негативно отразиться на разработке клиентской части, интеграции с веб-фреймворками, использовании библиотек тегов, использовании IDE и работе потоков.

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

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

Рисунок 2. Последовательность синхронной передачи данных
Последовательность синхронной передачи данных

В модели асинхронной передачи данных, взаимодействие между браузером (через веб-пользователя) и веб-сервером, сервером приложений, или веб-приложением не связаны. Во время обработки пары запрос/ответ, пользователь может продолжать использовать браузер, и во время обработки текущего асинхронного запроса. Как только обработка запроса будет завершена, будет передан асинхронный ответ (от веб-сервера, сервера приложений или веб-приложения) обратно на страницу клиента. Обычно, в течение этого процесса, вызов не влияет на действия пользователей; им нет необходимости ждать ответа.

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

Рисунок 3. Последовательность асинхронной передачи данных
Последовательность асинхронной передачи данных

Влияние на клиентскую часть

При внедрении Ajax в веб-приложение, команда разработчиков должна принять во внимание возможное возникновение нескольких проблем, в основном связанных с генерацией HTML-страницы, и ее взаимодействием с браузером. Эти проблемы хорошо описаны в статье Криса Лаффры (Chris Laffra) Рассматривая Ajax, состоящей из двух частей (см. Ресурсы). Необходимо отметить несколько важных вещей:

  • Возможно, не включена опция scripting: по разным причинам поддержка JavaScript может быть отключена в различных браузерах.
  • Поддержка различных браузеров повышает требования к коду: поддержка приложением многих браузеров и их версий может потребовать дополнительных усилий по написанию скриптов, так как существует много различий в способах, которыми браузеры интерпретируют DOM элементы (а потому должно быть также различие в коде JavaScript, который оперирует этими элементами).
  • JavaScript не является защищенным: в большинстве браузеров исходные коды на JavaScript, связанные со страницей, можно просмотреть, просто выбрав опцию view source. Используя Ajax, убедитесь, что логика вашего кода является открытой.

Интеграция с сетевыми структурами

Вполне естественны попытки осуществить интеграцию Ajax с выбранной сетевой структурой Java EE. Но некоторые структуры Java EE пока еще не предоставляют поддержку модели асинхронной передачи данных. Чтобы понять, последствия этого факта, вам нужно понять, каким образом сервлеты организуют синхронную передачу данных в сравнении с асинхронной. Рисунок 4 показывает традиционную последовательность управления синхронным запросом.

Рисунок 4. Последовательность управления синхронным запросом
Традиционная последовательность сервлетов (синхронная)

Для веб-разработчиков Java EE рисунок 4 должен показаться довольно знакомым. Сначала запрос от браузера управляется контроллером service(). Этот сервлет получает любое необходимое значение из HttpRequest (параметр или атрибут). Как только завершена контроллерная обработка, её результат отсылается обратно в HttpRequest (или HttpSession), и RequestDispatcher передает управление обратно на страницу.

Рисунок 5 показывает последовательность для обработки асинхронного запроса.

Рисунок 5. Последовательность для обработки асинхронного запроса
Последовательность сервлетов (асинхронная)

Последовательность на рисунке 5 немного отличается от синхронной. Сначала запрос от браузера управляется контроллером service(). Этот сервлет получает любое значение, которое ему нужно из HttpRequest (параметр или атрибут). Но когда контроллерная обработка завершена, тип контента HttpServletResponse должен быть указан в XML. Также, результат обработки должен быть записан в PrintWriter. Здесь использование RequestDispatcher игнорируется.

Дело в том, что как раз эта (асинхронная) последовательность не поддерживается в большинстве веб-структур Java EE, что усложняет интеграцию с Ajax. Портлеты и структуры JavaServer Faces (JSF), которые не поддерживают асинхронную модель передачи данных сталкиваются с той же проблемой.

У вас есть несколько вариантов преодоления этой ситуации:

  • Пользуйтесь существующими веб-структурами: вместо того, чтобы ждать, когда будет осуществлена поддержка Ajax в выбранных структурах, вы можете создать отдельный сервлет для обработки всех асинхронных запросов. DWR использует как раз такой подход. Обратная сторона медали в том, что запрос Ajax не может легко увеличить возможности вашей структуры.
  • Совершенствуйте веб-структуру: используя расширения, которые имеются в свободном доступе, вы можете придумать способ совершенствования веб-структуры.
  • Переходите на структуры, поддерживающие Ajax: новейшие структуры начинают поддерживать синхронную модель. Например, Apache Shale (см. Ресурсы).

Использование библиотек тегов

Использование библиотек тегов при разработке веб-приложений очень распространено. Как и многие веб-структур Java EE, некоторые библиотеки тегов в настоящее время не поддерживают новую асинхронную модель, не оставляя вам возможности перевести данные отправленные через XMLHttpRequest в HttpServletRequest и наоборот). По сути, библиотеки, которые не поддерживают асинхронную передачу данных, становятся бесполезными на время вызова Ajax XMLHttpRequest. Варианты такие:

  • Не используйте библиотеки тегов, которые не поддерживают асинхронную модель: перейдите с кода, который сейчас вы генерируете при помощи библиотек тегов, на код HTML/JavaScript. (Если веб-приложение сильно зависит от библиотек тегов, этот способ, в конечном счете, приведет к увеличению размеров view-уровня.)
  • Обойдите эту проблему: используйте структуры Ajax, которые позволяют обойти эту проблему. Один из примеров – DWR (см. ExecutionContext.forwardToString()). В этом случае вы можете продолжать применять библиотеки тегов, которые вы использовали.
  • Используйте библиотеки тегов, поддерживающие Ajax: используйте библиотеки тегов, которые поддерживают асинхронную модель, например, Ajax JSP Tag Library (AjaxTags) (см. Ресурсы).

Разработка и отладка с IDE

Существует масса доступных инструментов отладки JavaScript, которые помогут разработчикам в создании JavaScript-решений. Однако традиционные среды разработки Java не позволяют исследовать значения в XMLHTTPRequest и других параметрах Ajax.

Одно из решений – использование AJAX Toolkit Framework (ATF) (см. Ресурсы). ATF – это дополнение к Eclipse с усовершенствованными инструментами редактирования JavaScript такими, как проверка синтаксиса во время редактирования, встроенный браузер Mozilla, встроенный браузер DOM и встроенный отладчик JavaScript. Кроме того, ATF включает в себя функцию Personality Builder, которая помогает при создании элементов IDE для произвольных run-time структур Ajax.

Проблемы работы потоков

В типичных синхронных веб-приложениях, некоторые области отнимают довольно продолжительное время на обработку нажатия кнопки или ссылки. Нетерпеливые и неопытные пользователи зачастую вызывают множество процессов отправки формы, нажимая на кнопку или ссылку более одного раза, ожидая, что это поможет ускорить процесс. Или пользователь может думать, что нужно двойное нажатие (как в настольных приложениях). Множественное дублирование процесса отправки формы в некоторых случаях безвредно. В других же, побочные эффекты могут вызвать серьезные проблемы с организацией поточной работы или эффект гонки (когда многочисленные процессы «соревнуются» за выполнение части кода). Например, неоднократные нажатия на кнопку передачи средств в банковском приложении могут послужить причиной непреднамеренных повторных транзакций.

Если веб-приложение поддерживает как синхронные, так и асинхронные модели взаимодействия, могут возникнуть проблемы в случае, когда его работа неправильно проанализирована и спланирована. В приложении, которое поддерживает обе модели передачи данных, может возникнуть путаница с вызовами на данной странице (то есть, исключительно синхронные, исключительно асинхронные и смесь синхронных и асинхронных). Как и в сценарии «многократного щелчка», асинхронный вызов может обрабатываться немного медленнее. И пользователь, если приложение не предотвращает этого, может вызвать синхронный запрос во время обработки асинхронного потока, поскольку страница не обновляется и поэтому не предотвращает дальнейшую активность на странице. Конечный результат – то, что эти два процесса обработаны одновременно. Даже если они не вызваны нажатием одной и той же кнопки или ссылки, такие ситуации могут вызывать проблемы поточной работы (подобно проблеме «многократного щелчка») в коде программы сервера.

В качестве примера возьмем страницу перевода средств в банковском приложении, показанную на Рисунке 6:

Рисунок 6. Транзакционный пример
Транзакционный пример

В этом примере, кнопка Transfer Funds (Перевод средств), изображенная красной, вызывает запрос Ajax. Ссылка Logout (Выход) (желтая) вызывает синхронный запрос. Если нетерпеливый или неопытный пользователь нажмет последовательно красную кнопку и желтую ссылку (предполагается, что обе ссылки имеют общий путь в коде), в конечном счете, может произойти эффект гонки.

У вас есть два способа избежать этой ситуации. Первый – это решение на базе программы-клиента. Используйте JavaScript для того, чтобы, как только ссылка или кнопка была нажата, дальнейшие попытки отправки формы были запрещены до тех пор, пока текущий поток не будет обработан. Второе решение состоит в том, чтобы разрешить многократные отправки потоков, полагаясь на синхронизацию с серверной частью, чтобы избежать эффекта гонки. Если вы выбрали синхронизацию для решения этой проблемы, не забудьте, что веб-компоненты Java EE (сервлеты, портлеты, JSF и т.д.) являются многопоточными. Будьте осторожны с синхронизацией больших кусков кода (особенно кода, относящегося к циклу обработки запроса/ответа). Неправильное использование синхронизации может превратить приложение в однопоточное, уменьшая его производительность.


Преодоление ошибок выполнения

Использование Ajax может влиять на выполнение веб-приложений, основанных на Java EE. Возможность добавления дополнительных потоков по запросу может повлиять на два элемента.

Во-первых, возможно воздействие на поточный пул сервлет-контейнера. Это средство определяет максимально возможное число потоков, которые могут быть запущены в веб-контейнере одновременно. Для каждого запроса клиента требуется один поток. Однако, запрос клиента не обязательно равен запросу пользователя. Браузеру может потребоваться несколько клиентских запросов на один пользовательский. Например, несколько клиентских запросов могут быть необходимы чтобы осуществить операцию пользователя «отправить форму» (submit) (которая содержит в себе отправку значения полей формы, получение gif-файлов, получение файлов JavaScript, и получение файлов CSS). Если разрешено одновременное подтверждение синхронных и асинхронных запросов, то такая ситуация означает затрату еще одного потока (для запроса Ajax) на каждый запрос пользователя. Хотя возможная необходимость добавления еще одного потока для каждого запроса пользователя не кажется страшной, последствия этого становятся очевидными во время процесса загрузки приложения (когда каждый дополнительный поток на пользовательский запрос умножается на среднее число пользователей). Очевидно, что эта ситуация может влиять на выполнение сервлет-контейнера.

Также возможно воздействие на средства соединения с базами данных (database connection pool). Типичное веб-приложение на Java EE разрешает два типа последовательности пользовательского запроса: поверхностные запросы и глубокие запросы. Поверхностный запрос – это запрос, который создается из веб-страницы и исполняется на сервере, но не имеет доступа к постоянному хранилищу данных (такому как база данных) для завершения запроса. Глубокий запрос – наоборот.

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

  • Среднее число потоков, ожидающих соединения
  • Среднее время ожидания для соединения в миллисекундах
  • Среднее время соединения

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


Тестирование

Java-разработчики всегда акцентировали внимание на необходимости предоставления инструментов для тестирования Java SE и Java EE кода. Так как количество JavaScript в браузерах возрастает с внедрением Ajax, то поэтому требуется надежная база для тестирования. Сейчас доступны JsUnit, Selenium, и HttpUnit (см. Ресурсы).

Эти ресурсы предоставляют инструменты для разработки тестов тех функций JavaScript, которые управляют DOM-элементами на веб-страницах. Также они позволяют группировать единичные тесты в наборы. Средство тестирования совместимости в браузере Selenium позволяет вам тестировать функции JavaScript на различных браузерах и операционных системах. Здесь используются JavaScript и Iframes для встраивания механизма тестирования в ваш браузер. Эта техника должна работать во всех браузерах, которые поддерживают JavaScript и является особенно полезной для приложений, которые поддерживают множество различных браузеров и их версий. Как Selenium, так и JsUnit поддерживают непрерывную интеграцию: вы можете встраивать как единичные тесты, так и наборы тестов JavaScript в автоматизированный процесс сборки.


Вывод

Внедрение Ajax, как и любой другой технологии, в приложение Java EE имеет свои недостатки и преимущества. Эта статья дает вам общее представление об интеграции Ajax в веб-приложения Java EE. Модель асинхронного передачи данных в Ajax достаточно сильно отличается от синхронной модели, которая традиционно используется в построении веб-приложений на Java EE. Чтобы избежать неожиданностей, заранее продумывайте потенциальные проблемы, прежде чем использовать Ajax.

Поддержка Ajax в структурах и утилитах Java EE продолжает совершенствоваться. Чтобы уменьшить сложность внедрения Ajax, обратите внимание на новейшие системы поддерживающие ее. За чем стоит следить, так это за основанной на JSF Apache Shale и DWR, базирующейся на сервлетах.

Ресурсы

Научиться

Получить продукты и технологии

  • AJAX Toolkit Framework: технология от IBM alphaWorks, которая помогает в построении системной поддержки Eclipse инструментов Ajax и предоставляет усовершенствованные DHTML/JavaScript IDE инструменты для Ajax-разработчиков.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, XML
ArticleID=209537
ArticleTitle=Упростите интеграцию Ajax и Java EE
publish-date=05082007