Приложения Web 2.0, которые отличаются более динамичной работой, часто используют Asynchronous JavaScript и XML (Ajax). Загрузив основной документ HTML, вы можете использовать Ajax для обновления web-контента, не обновляя web-страницу полностью. Благодаря Ajax, можно обрабатывать web-контент в виде фрагментов данных, вызывая каждый из них при необходимости. Кроме того, процессы JavaScript на стороне клиента могут сами форматировать данные, в том числе данные в формате простого текста, XML, объекты JavaScript Object Notation (JSON) или фрагменты HTML.
Новая парадигма разработки web-приложений идет гораздо дальше традиционной модели Model-View-Controller (MVC). К сожалению, многие инфраструктуры web-приложений Ajax, например, Direct Web Remoting, DWR (Непосредственное удаленное web-взаимодействие) и JavaServer Faces (JSF), могут вызывать проблемы. Хотя инфраструктура Ajax может во многом упростить разработку приложений, механизм инфраструктуры не всегда одинаково контролирует web-контент. Многие из существующих инфраструктур Ajax не предоставляют универсальных решений, которые способны справляться со сложностями реального мира, особенно при всевозрастающих требованиях к агрегации данных из XML и синдикации контента из каналов RSS. Эти новые требования диктуют потребность в эффективной поддержке web-сервиса на стороне сервера.
Чтобы воспользоваться преимуществом этих изменившихся технологий, можно создать гибридное приложение, которое комбинирует web-контент c XML-данными и web-сервисами. В этой статье будет продемонстрировано, как создать гибридное приложение, которое использует XQuery, многообещающую технологию для работы с web-сервисами и XML.
Пример гибридного приложения позволяет пользователям осуществлять поиск новых книг в системе публичной библиотеки, которая включает все библиотеки в данном регионе. В каждой библиотеке сотрудники регулярно заказывают новые книги, не зная, есть ли такие книги в других библиотеках. Приложение публикует и предоставляет в общее пользование собственную информацию о хранении через web-сервис. Оно собирает всю информацию о новых книгах по библиотекам и предоставляет пользователям функцию поиска новых книг.
XQuery - это стандарт консорциума W3C, разработанный специально для извлечения информации из XML документов. Его возможности по обработке XML имеют много преимуществ по сравнению с существующими моделями объектного программирования, например, API™ объектной модели документов (Document Object Model, DOM) Java (в разделе Ресурсы можно найти несколько ссылок на сайт IBM developerWorks по этой теме).
Упрощение обработки XML на стороне сервера
Конечно, можно использовать JavaScript для синтаксического разбора и обработки XML в рамках API DOM. Но это не означает, что вы можете использовать JavaScript для любых задач по обработке XML на стороне клиента. Это особенно верно в том случае, когда процессы бизнес-логики становятся более сложными. Одной из главных проблем при разработке web-приложений является поиск равновесия между обработкой XML на стороне клиента и на стороне сервера. XQuery переводит комплекс бизнес-логики на сторону сервера, что имеет ряд преимуществ. Например, можно более тщательно продумать проблемы безопасности и с большей легкостью осуществлять управление приложением. Кроме того, функции XQuery упрощают общие затраты ресурсов на разработку.
Ограничение объема контента, передаваемого по сети
При разработке web-приложения необходимо решить, какой объем контента предполагается и как часто он будет передаваться по сети. Каждый вызов сервера увеличивает нагрузку. Избегайте асинхронных вызовов при каждом нажатии на клавиатуру или движении мыши. Если вы неправильно используете вызовы сервера, то можете легко нарушить передачу данных приложением из-за ненужного сетевого трафика и загрузки.
При сетевом коммутируемом подключении со скоростью 56K на передачу 100 кБайт контента требуется 14 секунд. XQuery предоставляет пользователю лучшие возможности для работы, уменьшая объем контента, передаваемого по сети. Например, чтобы ограничить объем контента XML, можно вызвать стандартную функцию XQuery string-length() до того, как будет возвращен XML. Вместо того, чтобы ограничивать объем контента XML, наш пример приложения ограничивает размер объектов XML 100 экземплярами книг, считая узлы.
Интеграция нескольких полей поиска
Иногда системы web-поиска используют несколько полей ввода для критериев поиска. Например, наш пример приложения предлагает пользователям три варианта на выбор. Они могут ввести данные в одно из полей или в любую комбинацию этих полей, в том числе и во все три поля. Функциии XQuery в сочетании с выражениями пути XPath предоставляют эффективный механизм поиска для реализации требований к поиску.
Интеграция бизнес-логики без дополнительного программирования
XQuery - это декларативный язык запросов. Для упрощения интеграции существующих данных и сервисов при помощи XML, он инкапсулирует бизнес-логику в компактную форму. Вывод запроса может быть в форматах, определяемых пользователем, поэтому несложно реализовать бизнес-логику без дополнительного программирования.
Рисунок 1 демонстрирует пример приложения. Ответы сервера могут быть в любом удобном для клиента формате, в том числе, HTML, XML, простом текстовом формате или в виде объекта JSON. Встроенный механизм XQuery выполняет заранее определенный запрос, основываясь на динамических критериях поиска. Вы определяете бизнес-логику и представление логики в запросах. Данные XML могут поступать из различных ресурсов данных, таких как файловая система, база данных или URI, который представляет web-сервис стандарта REST (Representational State Transfer, протокол передачи состояния для интерпретации в представлении).
Рисунок 1. Принципиальная схема примера приложения
Механизм XQuery можно встроить в приложение при помощи базового сервлета Java. Вы можете выбрать любой из множества механизмов XQuery, коммерческий или с открытым исходным кодом. В этом приложении используется механизм с открытым исходным кодом Saxon 8.7 (см. листинг 1).
Листинг 1. Встраивание механизма XQuery Saxon
Configuration config = new Configuration(); staticQueryContext = new StaticQueryContext(config); dynamicQueryContext = new DynamicQueryContext(config); |
Сбор XML данных и определение форматов данных
Для сбора XML-данных необходимо решить, откуда будут поступать XML-данные, нужно ли использовать описание типа документа (шаблон DTD) или схему и нужно ли валидировать XML. Наше приложение использует для форматирования данных шаблон DTD и предполагает, что все источники данных перед обработкой XQuery являются корректными по DTD документами. Листинг 2 показывает пример форматирования XML-данных.
Листинг 2. Пример форматирования XML-данных
<?xml version="1.0" encoding="UTF-8"? > <!DOCTYPE library SYSTEM "dtd/book.dtd"> <booklist> <book category="COOKING"> <title lang="en">Everyday Italian</title> <authors> <author>Giada De Laurentiis</author> </authors> <isbn></isbn> <numberCopies>1</numberCopies> <status>On Shelf</status> <year>2005</year> <library>John C. Hart Library</library> <price>30.00</price> </book> ... </booklist> |
Описание запросов XQuery при помощи бизнес-логики
В бизнес-логике XQuery для поиска книг используется три поля ввода, поэтому необходимо спроектировать шесть стратегий запроса. Кроме того, необходимо продумать сценарий, который будет использоваться по умолчанию, если пользователь не определит параметры поиска. В отличие от традиционной инфраструктуры web-приложения, XQuery может может легко создать бизнес-логику в файле запроса. При необходимости в дальнейшем можно обновить этот файл, даже не останавливая выполнение приложения. Например, вы можете изменить запросы на книги, изданные в последние три года.
Данные XML могут поступать из множества ресурсов. Файл book_collection.xml file описывает коллекцию XML-данных. Один из источников данных XML принадлежит самому нашему примеру web-приложения и находится на узле http://localhost:9080/bookinfor/newbooks_localhost.xml. Тестируя пример приложения, убедитесь, что вы правильно задали корневой каталог контекста web-приложения как bookinfor. В листинге 3 показан сбор XML-данных.
Listing 3. XQuery collection
<collection > <doc href="newbooks_library_01.xml"/> <doc href="newbooks_library_02.xml"/> <doc href="newbooks_library_03.xml"/> <doc href="newbooks_library_04.xml"/> <doc href="http://localhost:9080/bookinfor/newbooks_localhost.xml"/> </collection> |
При разработке web-приложения XQuery обязательно учитывайте вопросы производительности. В этом случае я задал порог вывода результатов поиска в 100 книг. По сравнению с обычным объектным программированием, например, Java, XQuery может реализовать бизнес-логику без необходимости программирования на стороне сервера. Работая с большими объемами XML-данных, вы можете сочетать встроенный механизм XQuery с версией IBM DB2 Viper, которая способна манипулировать большим объемом контента XML (до 2GB). В листинге 4 иллюстрируется бизнес-логика приложения в файле booklist_app.xql.
Листинг 4. XQuery с простой бизнес-логикой
(: -------------------------- :)
(: -------------------------- :)(: :)
(: -------------------------- :)
declare namespace local = "http://localhost/ns";
declare variable $title as xs:string external;
declare variable $author as xs:string external;
declare variable $year as xs:string external;
declare variable $emptymsg as xs:string external;
declare variable $oversizedmsg as xs:string external;
declare variable $outputformat as xs:string external;
(: -------------------------- :)
(: functions :)
(: -------------------------- :)
declare function local:error_view($helpmsg as xs:string) {
if($helpmsg) then $helpmsg
else ('<report status="0">Please call 1-800-123-4567</report>')
};
declare function local:html_view($doc) {
<table>
<tr> <td>Library Name</td>
<td>Book Title</td>
<td>Number of Copies</td>
<td>Status</td>
</tr>
{ for $book in $doc/book
where $book/title/@lang="en"
order by $book/library
return <tr>
<td>{$book/library}</td>
<td>{$book/title/text()}</td>
<td>{$book/numberCopies}</td>
<td>{$book/status}</td>
</tr>
}
</table>
};
(: -------------------------- :)
(: the business logic :)
(: -------------------------- :)
let $docs := ('bookinfor/book_collection.xml')
let $searchdoc := (
<report status='1'>
{
if($title and $year and $author) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)
and (year = $year)]
where contains($doc//authors, $author)
return $doc
) else if($title and $year ) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)
and (year = $year)]
order by $doc//booklist/book/title
return ($doc)
) else if($title and $author ) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)]
where contains($doc//authors, $author)
order by $doc//booklist/book/title
return ($doc)
) else if($author and $year ) then (
for $doc in collection($docs)//booklist/book[(year=$year)]
where contains($doc//authors, $author)
order by $doc//booklist/book/title
return ($doc)
) else if($title) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)]
order by $doc//booklist/book/title
return ($doc)
) else if($author) then (
for $doc in collection($docs)//booklist/book
where contains($doc//authors, $author)
order by $doc//booklist/book/title
return ($doc)
) else if($year) then (
for $doc in collection($docs)//booklist/book[(year=$year)]
order by $doc//booklist/book/title
return ($doc)
) else (
for $doc in collection($docs)
return ($doc//booklist/book)
)
}
</report>
)
(: -------------------------- :)
(: return results :)
(: -------------------------- :)
return if(count($searchdoc//book) eq 0) then local:error_view($emptymsg )
else if(count($searchdoc//book) gt 100)
then local:error_view($oversizedmsg)
else if($outputformat eq $html)
then local:html_view($searchdoc)
else $searchdoc
|
Вызов запросов XQuery в приложении
Чтобы добиться выполнения запросов встроенным механизмом, вам необходимо задать относительные параметры и перекомпилировать запрос. После выполнения запроса окончательный вывод пересылается обратно web-клиенту. Программа JavaScript осуществляет сборку данных и создает их представление для пользователя. Обратите внимание, что наше приложение устанавливает каталог c:/tmp/xmldatasources/ в качестве каталога статического контекста запроса. Убедитесь, что в этом каталоге существует каталог bookinfor и скопируйте в него файлы XML-данных до тестирования примера приложения. Листинг 5 иллюстрирует вызовы встроенного механизма XQuery.
Листинг 5. Вызов запросов XQuery в приложении
dynamicQueryContext.setParameter("emptymsg", "No results exist!");
dynamicQueryContext.setParameter("oversizedmsg",
"Too many results, please refine queries");
staticQueryContext.setBaseURI("c:/tmp/xmldatasources/");
fileReader = new FileReader(request.getRealPath("/")+ "/queries/booklist_app.xql");
queryExpression = staticQueryContext.compileQuery(fileReader);
writer = new StringWriter();
StreamResult result = new StreamResult(writer);
Properties props = new Properties();
queryExpression.run(dynamicQueryContext, result, props);
retContent = writer.getBuffer();
|
Обратите внимание, что технология XQuery все еще имеет некоторые ограничения и достаточно сложную кривую обучения. Имейте в виду, что ни одна технология не может решить всех бизнес-проблем. Скорее всего, вам и дальше придется комбинировать XQuery с другими технологиями, например, с XPath и XSLT, чтобы добиться доступности гибридных приложений.
Хотя XQuery до сих пор не имеет окончательного стандарта, его основные функции и свойства привлекают повышенное внимание. Эта технология эффективна при обработке XML и демонстрирует большой потенциал в настройке гибридных приложений. Реализовав динамичное web-приложение при помощи XQuery, вы сможете быстро масштабировать свой web-сайт и решить бизнес-задачи сравнительно простым и быстрым способом.
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| Sample code for XQuery to power mashups | x-xquerymashup.zip | 12KB | HTTP |
Научиться
- Оригинал статьи Power your mashups with XQuery;
- Освоение Ajax, часть 1: введение в Ajax, автор Бретт МакЛафлин (Brett McLaughlin): узнайте о том, как технологии Ajax работают вместе, преобразуя тяжеловесные web-интерфейсы в интерактивные web-приложения;
- Обсуждаем Ajax, часть 2: измените свою жизнь при помощи гибридных приложений, автор Крис Лаффра (Chris Laffra) (сайт developerWorks, май 2006 г.): прочитайте статью о том, как Ajax снабжает управляемые пользователем гибридные приложения контентом на индивидуализированных web-страницах;
- Debunking XQuery myths and misunderstandings (Разоблачение мифов и заблуждений об XQuery), автор Фрэнк Коэн (Frank Cohen) (сайт developerWorks, июль 2005 г.): отбросьте многие мифы и заблуждения, которые окружают XQuery;
- Java theory and practice: Screen-scraping with XQuery (Теория и практика Java: захват дампа экрана при помощи XQuery), автор Брайан Гетц (Brian Goetz) (сайт developerWorks, март 2005 г.): пример эффективного использования XQuery в качестве механизма захвата HTML-дампа экрана;
- Разрабатываем Java-приложение для XML-данных DB2, автор Синтия М. Саракко (Cynthia M. Saracco) (сайт developerWorks, май 2006 г.): пишите Java-приложения и создавайте хранимые процедуры, которые обращаются к XML-данным; научитесь вставлять, запрашивать, обновлять и удалять XML-данные;
- W3C XML Query (XQuery): поищите на домашней странице XQuery спецификации и другую информацию;
- Saxon 8.7: научитесь внедрять механизм XQuery в приложение;
- IBM XML 1.1 certification: узнайте, как стать сертифицированным разработчиком IBM в области XML 1.1 и смежных технологий;
- XML: Раздел XML на developerWorks Россия: технические статьи и советы, учебные руководства, стандарты;
Получить продукты и технологии
- IBM DB2 версия 9 Viper: загрузите бесплатную пробную версию.
Обсудить
Нинг Ян (Ning Yan) работает в качестве инженера по программному обеспечению в IBM. Сфера его профессиональных интересов - разработка web-приложений и бизнес-решений, в том числе DB2, WebSphere®и технологии с открытым исходным кодом. В настоящее время он занимается технологиями социального компьютинга и web-сервисами.