Поради щодо програмування Web-сервісів Вивчення шаблонів проектування Web-сервісів, Частина 1
Асинхронні операції Web-сервісів із використанням JMS
Серія контенту:
Цей контент є частиною # із серії # статей: Поради щодо програмування Web-сервісів
Цей контент є частиною серії: Поради щодо програмування Web-сервісів
Слідкуйте за виходом нових статей цієї серії.
Якщо уявити реалізацію Web-сервісів з SOAP, швидше за все, вам спадуть на думку прості синхронні операції типу запит-відповідь. Насправді Service-Oriented Architecture (SOA) може охоплювати набагато більший діапазон моделей обміну повідомленнями та стратегій проектування. У цьому документі ми сфокусуємось на застосуванні основних шаблонів проектування Web-додатків із використанням Web-сервісів. Шаблони, що представляються, не є новими, вони використовуються в традиційних Web-додатках вже багато років, проте багато розробників навіть не підозрюють про те, як реалізувати такі методики в області Web-сервісів або ж не до кінця розуміють, як їх застосовувати. Автор ставить собі завдання представлення набору простих, відкритих альтернатив проектування моделі запит-ответ. Для вивчення прикладу необхідно мати хоча б основні уявлення про реалізацію Web-сервісів у середовищі J2EE.
Шаблон асинхронного запиту
Щоб відкинути зайве, ми досліджуємо реалізацію асинхронних операцій запитів та відповідей з метою розбиття тривалих операцій, і щоб уникнути тайм-аутів або довгих відбоїв при виконанні коду. Якщо ви маєте досвід реалізації асинхронних запитів у традиційних Web-додатках HTTP і HTML, шаблон, що застосовується, повинен бути вам знайомий.
Малюнок 1. Шаблон асинхронного запиту


Потік у цій моделі дуже простий:
- Сторона, що запитує, передає запит до постачальника сервісу, той ставить повідомлення в чергу і повертає ID кореляції, який сторона, що запитує, пізніше може використовувати для перевірки статусу запиту.
- Обробник запиту видаляє запит із черги та обробляє його. Зазвичай, обробка запиту є тривалим процесом. Після завершення обробки процесор ставить у чергу повідомлення відповіді.
- У деякий невизначений момент часу, сторона запитує постачальника сервісу на предмет готовності запиту. Якщо запит перебуває у черзі, постачальник повертає його назад. Якщо запит недоступний, постачальник повідомляє про це запитуючу сторону, яка може вибрати – скасувати запит або чекати на відповідь, опитуючи постачальника через певні проміжки часу на наявність готового запиту.
Проектування інтерфейсу сервісу
Для ілюстрування шаблону асинхронного запиту ми реалізуємо простий приклад Web-сервісу, який поза цим прикладом немає особливого практичного значення. Даний сервіс виконує просте перетворення трьох вхідних значень типу String із нижнього регістру у верхній після застосування 10 секундної затримки (для симуляції тривалих процесів).
Для реалізації цього сервісу доступні дві операції: submitRequest і checkResponse . Дія цих операцій вимагає пояснення. У Лістингу 1 представлений WSDL, що описує інтерфейс сервісу.
Лістинг 1. AsyncService.wsdl
Тут слід зазначити кілька моментів:
- Сервіс використовує стиль написання коду RPC/Literal.
- Обидві операції submitRequest і checkResponse повертають об'єкт з ім'ям Response. Існує два різновиди Response, що визначаються властивістю типу (type property).Значення властивості типу 0 вказує на Refresh Response, а значення 1 - на Request Response. Refresh Response вказує на те, що відповідь ще не доступна і сторона, що запитує, повинна підтвердити нову операцію checkResponse не раніше, ніж зазначено в значенні властивості оновлення (еквівалентно механізму HTTP META Refresh , що обговорюється в статті Kyle Brown). Request Response містить три рядки введення у верхньому регістрі та представляє завершення обробки запиту.
- Refresh Response містить властивість Correlation ID, чиє значення використовується як введення для операції checkResponse. Цей ідентифікатор є єдиним засобом зіставлення клієнтом початкового запиту з відповіддю. Існують також інші способи для цієї реалізації, про які буде розказано пізніше.
У Лістингу 2 представлений типовий обмін повідомленнями даного сервісу.
Лістинг 2. Обмін повідомленнями AsyncService
Реалізація сервісу
Реалізацією сервісу асинхронного шаблону запиту є застосування Java Messaging Service. Для ілюстрації прикладу тут використовується OpenJMS – реалізація постачальника JMS з відкритим вихідним кодом (див. Ресурси на тему) та IBM® WebSphere® Application Server V5 (сервер додатків). У прикладі використовується конфігурація OpenJMS, визначена за умовчанням, і навіть реалізація Web-сервиса J2EE, сумісного з JSR-109. Код для цього прикладу написаний за допомогою WebSphere Studio Application Developer (Application Developer) V5.1, який можна завантажити за посиланням з сайту developerWorks (див. Ресурси по темі). Тут також додається EAR-файл (див. Ресурси на тему) на той випадок, якщо у вас немає доступу до Application Developer.
На стороні сервера необхідно реалізувати два компоненти – обробник запитів тареалізація Web-сервісу. Завданням обробника запитів є зняття запитів із черги та виконання 10-секундної затримки процесу перетворення нижнього регістру символів у верхній. Завданням реалізації сервісу є отримання запитів від клієнтів Web-сервісу та постановка їх у чергу для обробки та доставки відповідей клієнтам, слідуючи операції checkResponse.
У типовому додатку J2EE, згідно специфікації JMS, обробник запитів має бути реалізований як Message Driven Bean (компонент, керований повідомленнями). У цьому прикладі використовується простий HTTP-сервлет, що реалізує JMS-інтерфейс MessageListener. Сервлет налаштований на ініціалізацію під час завантаження сервера, що дозволяє слухачеві бути доступним для всіх можливих запитів. Після постановки запиту до черги той доставляється сервлету-слухачу.
Лістинг 3. JNDIListenerServlet.java
Сервлет JNDIListenerServlet та реалізація сервісу використовують один простий допоміжний клас, створений для цієї програми, який приховує деталі ініціалізації JMS-з'єднання та сесії.
Лістинг 4. JNDIHelper.java
Після створення сервлета відредагуйте файл Web-програми web.xml таким чином, щоб сервлет ініціалізувався під час завантаження сервера. При ініціалізації сервлет створює JMS-з'єднання та реєструє себе як слухач у черзі повідомлень OpenJMS, заданої за замовчуванням.
Другим кроком є створення реалізації сервісу. Тут може стати в нагоді робота з Application Developer, який може допомогти в генеруванні різних артефактів для отримання працюючого JSR-109 Web-сервісу. Тепер сфокусуємось виключно на класі реалізації сервісу. Для ілюстрації інших різних конфігураційних файлів Java і XML до цього документа додається вихідний код,який може бути завантажений за посиланням наприкінці документа.
Лістинг 5. AsyncService.java
У цьому списку немає нічого незвичайного. Метод submitRequest готує JMS MapMessage на основі вхідних параметрів. Це повідомлення складається із трьох рядкових значень. Після цього повідомлення відправляється в чергу та готується Refresh Response, що містить ID кореляції, після чого той повертається клієнту.
Операція checkResponse приймає ID кореляції із вхідних параметрів та встановлює з'єднання з чергою відповіді, запитуючи доставку будь-яких повідомлень з відповідним ID кореляції. Якщо таких повідомлень не існує, операція не чекає на них, а готує інший Refresh Response з новим періодом інтервалу оновлення і повертає його зворотній стороні. Якщо повідомлення доставлено, операція готує та повертає відповідний Request Response.
Для запуску Web-сервісу асинхронного шаблону запиту необхідно розмістити Web-сервіс та запустити сервери OpenJMS та WebSphere.
Основною перевагою шаблону асинхронних запитів є можливість кореляції запитів та відповідей клієнтом Web-сервісів та постачальником сервісу. У наведеному прикладі було розглянуто простий ID кореляції одноразового використання і механізм оновлення таймера, властивого цьому окремому прикладу програми. З цією ж метою можна використовувати, наприклад, кілька комбінацій WS-* специфікацій. WS-Addressing Endpoint Reference або WS-Transaction Coordination Context також можуть містити ID кореляції та оновлювати значення таймера. Використання цього шаблону індивідуально для окремих додатків, і незалежно від того, чи ви використовуєте стандартні елементи заголовка SOAP і різні WS-* специфікації, поведінка кожної реалізації операції повиннабути чітко визначено та задокументовано.
У реалізованому прикладі для надсилання запитів і отримання відповідей використовується традиційний шаблон обміну повідомленнями SOAP типу запит-відповідь. В якості альтернативи можна використовувати шаблон у стилі REST, в якій запити надсилаються сервлет методом HTTP POST, а відповіді витягуються з використанням методу HTTP GET. Кожен з цих підходів є однаково допустимим і має власні переваги і недоліки. Вибір підходу здійснюється залежно від вимог вашої програми. Наприклад, якщо операція checkResponse вимагатиме використання аутентифікації WS-Security, то використання моделі взаємодії в стилі REST немає сенсу.
У висновку, можна легко уявити розширення області застосування даного прикладу для виконання запитуючими сторонами детальних запитів статусу в тривалих операціях або навіть для скасування операцій, що вже виконуються. Ілюстрація таких можливостей не є завданням цієї статті, вам пропонується досліджувати їх самостійно.
Ресурси для скачування
- цей контент у PDF
- ws-tip-altdesign1ear.ear">Розміщений EAR-файл WebSphere (ws-tip-altdesign1ear.ear 701 KB)
- ws-tip-altdesign1code.zip">Вихідники програми-прикладу (ws-tip-altdesign1code.zip 719 KB)