Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
107
Добавлен:
02.05.2014
Размер:
6.34 Mб
Скачать

196 Часть II. Основные подходы к разработке приложений

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

5.3.4. Архитектуры, ориентированные на использование Web-служб

Последняя архитектура из рассматриваемых в данной главе, — это SOA (service-oriented architecture), т.е. архитектура, основанная на использовании служб. В данном случае служба — это нечто, к чему можно обратиться по сети, и получить в качестве ответа структурированный документ. Основное внимание здесь уделяется не содержимому, а данным, что вполне соответствует принципам Ajax. В настоящее время наиболее часто используются Web-службы, a XML в качестве основного языка также с энтузиазмом воспринимается разработчиками Ajax-приложений.

На заметку Термин Web-служба можно понимать как в широком, так и в узком смысле. Web-служба в узком смысле — это средства, использующие протокол SOAP. Web-служба в широком смысле — это любая система обмена данными, базирующаяся на протоколе HTTP, независимо от того, применяется ли при ее работе протокол SOAP или формат XML. XML-RPC, JSON-RPC и любая система, которую вы разработаете, используя объект XMLHttpRequest, будет Web-службой в широком смысле.

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

Предоставление доступа к объектам на стороне сервера

Многие инструментальные средства позволяют представить обычный объект, созданный на Java, С# или РНР, как Web-службу. При этом поддерживается отображение методов объекта в интерфейс Web-службы. Такую возможность предоставляют, в частности, Microsoft Visual Studio и Apache Axis for Java. Многие инструменты Ajax, например DWR (для Java) и SAJAX (для РНР,

.NET, Python и некоторых других языков), обеспечивают данную возможность посредством клиентского кода, написанного на языке JavaScript.

Глава 5. Роль сервера в работе Ajax-приложения 197

Применение инструментальных средств может существенно помочь при здании приложения. Если же использовать их неумело, результат будет противоположным. Для того чтобы составить представление о правильном использовании инструментов, рассмотрим простой пример, в котором применяется Java DWR. Мы определим объект на стороне сервера для предостав-

ления персональной информации.

package com.manning.aj axinaction; public class Person{

private String name=null; public Person(){

}

public String getName(){ return name;

}

public void setName(String name){ this.name=name;

}

}

Данный объект должен соответствовать спецификации JavaBeans. Это означает, что он должен предоставлять конструктор, вызываемый без параметров, и обеспечивать доступ к требуемым полям для чтения и записи посредством get- и set-методов. Далее мы сообщаем DWR о том, что данный объект должен быть доступен уровню JavaScript. Для этого мы редактируем файл dwr.xml.

<dwr>

<init>

<convert id="person" converter="bean" match="com.manning.aj axinaction.Person"/>

</init>

<allow>

<create creator="new" javascript="person"> <param name="class"

value="com.manning.aj axinaction.Person"> </create>

</allow>

</dwr>

В разделе i n i t мы определяем средства преобразования нашего класса в тип bean, а в разделе allow определяем средства, представляющие данный объект JavaScript-программам в виде переменной person. Наш объект Person содержит только один общедоступный метод, getName (), таким образом, мы можем включить в код клиента Ajax следующее выражение:

var name=person.getName() ;

Затем можно получать требуемое значение с сервера в асинхронном режиме.

В нашем классе Person содержится только один метод. На первый взгляд может показаться, что им и исчерпывается набор средств, которые предоставляются клиенту. На самом деле это не так. Класс Person является подклассом java.lang.Object и наследует от него ряд общедоступных методов, например hashCode () и tostring (). К ним также может производиться об-

198 Часть II. Основные подходы к разработке приложений

ращение. Эти "скрытые" средства не являются специфическими для DWR. Метод JSONRPCBridge. registerObject (), например, делает то же самое. Следует заметить, что DWR позволяет ограничить доступ к определенным методам, настраивая конфигурационный XML-файл. Однако по умолчанию доступ предоставляется ко всем методам. Такая проблема типична для решений, основанных на отражении. Мы встретились с ней в главе 4 при создании первых вариантов Obj ectviewer. Рассмотрим способы ее решения.

Предоставление ограниченного доступа

Если мы ненамеренно дадим возможность пользователям Web вычислять хэш-коды наших объектов, может ли это представлять опасность для нас? Для рассматриваемого примера, по-видимому, нет, так как суперклассом создаваемого нами класса является java.lang.Object, и эта ситуация вряд ли изменится. Для более сложных моделей, предоставляя информацию о суперклассе, мы не гарантируем, что программа в дальнейшем не подвергнется реструктуризации. Вполне может получиться так, что разработчик клиентской программы захочет воспользоваться методами, доступ к которым вы непреднамеренно предоставили. Затем, когда реструктуризированная модель будет доставлена на сервер, программные средства на стороне клиента внезапно откажутся работать. Другими словами, такое решение препятствует корректному разделению функций между клиентом и сервером. Если вы используете инструментальные средства, подобные DWR или JSON-RPC, вам следует тщательно взвешивать решения относительно состава интерфейса Ajax. Возможно, вам даже придется создать нечто вроде объекта Facade (рис. 5.5).

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

Еще одно преимущество Facade состоит в том, что данный образ разработки позволяет определять степень детализации предоставляемых услуг. Хорошая модель предметной области обычно содержит большое количество методов, выполняющих несложные действия. Таким образом, удовлетворяется требование детального управления работой кода на стороне сервера. Ajaxклиент предъявляет к интерфейсу Web-службы совершенно другие требования; они вытекают из наличия задержки, связанной с передачей данных по сети. Большое количество методов, решающих частные задачи, резко снизит практичность клиента, а сервер может не справиться с большим количеством запросов, передаваемых по сети.

Различие требований к интерфейсу, предъявляемых клиентом и сервером, можно проиллюстрировать на примере. Сравним разговор с обменом письмами. (Говоря о письмах, мы имеем в виду не электронную почту, а именно

Глава 5. Роль сервера в работе Ajax-приложения 199

Web-сервер

Рис. 5.5. Одна из систем предоставляет Ajax-клиенту все объекты как Интернет-службы, а при создании другой использован образ разработки Facade, который гарантирует доступ лишь к ограниченному набору функций. Уменьшая число общедоступных методов, мы снижаем риск повредить клиентский код при реструктуризации серверных программ

письма, написанные на бумаге, доставка которых занимает несколько дней.) Когда два человека беседуют, как минимум несколько фраз, которыми они обмениваются друг с другом, посвящено теме "как дела?". При написании письма никто не позволяет себе задать один подобный вопрос и ждать ответа на него. Отправитель подробно описывает, как его здоровье, как он провел отпуск, какие новости он узнал недавно, — все это оформляется в виде одного документа.

Путем объединения отдельных запросов, предназначенных для передачи по сети, в один большой документ архитектура, ориентированная на использование сетевых служб, позволяет более эффективно применять доступные сетевые ресурсы. Как правило, проблема быстродействия линий связи решается проще, чем проблема задержки при передаче по сети. Существует также проблема выработки стандартов для передачи больших объемов данных в формате XML посредством знакомого всем протокола HTTP, но ее Мы рассматривать не будем. Если мы проанализируем возможности, предоставляемые Ajax, то увидим, что в нашем распоряжении есть встроенные в браузер средства поддержки HTTP и XML, поэтому имеет смысл создавать распределенную модель предметной области на базе документов.

200 Часть II. Основные подходы к разработке приложений

Типичный документ, например данная книга, состоит из абзацев, заголов-: ков, таблиц и рисунков. Аналогично, документ, содержащийся в обращении к службе, может содержать различные элементы, например, запросы, данные для обновления и оповещения. Образ разработки Command, который обсуждался в главе 3, позволяет представлять структуру документа в виде последовательности действий (которые при необходимости можно отменять), передаваемых между клиентом и сервером. Реализация подобной структуры будет рассмотрена далее в этой главе.

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

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

5.4. Частные решения: обмен данными

Впредыдущем разделе мы рассматривали глобальные архитектурные решения и обсуждали вопрос о том, насколько они подходят для создания Ajaxприложений. Мы постоянно подчеркиваем важность обмена данными между клиентскими программами и моделью предметной области, поддерживаемой на сервере. Прочитав материал, изложенный выше, можно сделать вывод, что, правильно выбрав базовые средства, мы автоматически решим последующие задачи. Увы, это совсем не так. И вы в этом убедитесь, прочитав остальную часть главы. Если мы внимательно рассмотрим вопрос обмена данными, то увидим, что для данной задачи существует множество решений. В последующих разделах мы кратко опишем их и попытаемся выяснить, какой язык наилучшим образом подходит для обмена данными в рамках приложения Ajax. Имея такую информацию, мы сможем принимать более обоснованные решения об использовании конкретных средств.

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

Глава 5. Роль сервера в работе Ajax-приложения 201

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

зере подробно рассмотрим остальные три категории.

5.4.1. Взаимодействие, затрагивающее только клиентскую программу

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

Остальные три категории предполагают обращение к серверу и отличаются в основном передаваемыми данными. Главные различия между этими типами взаимодействия описаны в следующих разделах; там же рассмотрены преимущества и недостатки каждого из них.

5.4.2. Пример отображения информации о планетах

Перед тем как заняться изучением различных механизмов обмена данными, представим себе простой пример, на котором будем проверять то или иное решение. Наше приложение будет представлять информацию о планетах Солнечной системы. В главном окне представлено изображение Солнечной системы с пиктограммой для каждой планеты. На сервере хранятся сведения о планетах; щелчком на пиктограмме, соответствующей планете, надо отобразить эти сведения в окне (рис. 5.6). Сейчас мы не будем использовать объект Objectviewer, который рассматривался в главе 4, но еще вернемся к нему.

В данном случае нас больше всего интересует процесс доставки данных, которые должны быть отображены. Мы обсудим форматы данных, передаваемых сервером, но не будем углубляться в детали их генерации, так как этот вопрос был рассмотрен в главе 3. В листинге 5.1 показана заготовка клиентского кода приложения. На ее основе мы будем исследовать различные Механизмы доставки данных.

202 Часть II. Основные подходы к разработке приложений

I

Рис. 5.6. После щелчка на пиктограмме, соответствующей планете, информация о ней выводится в окне

Листинг 5.1. Содержимое файла popups .html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtmll/DTD/xhtmll-strict.dtd"> <html> <head> <title>Planet Browser</title>

<link rel=stylesheet type="text/css" href="main.css"/>

<link rel=stylesheet type="text/css" href="windows.ess"/>

<link rel=stylesheet type="text/css" href="planets.css"/>

// О Включение библиотек JavaScript <script type="text/javascript"

src="x/x_core. j s"x/script> <script type="text/javascript" src="x/x_event. j s"x/script> <script type="text/javascript"

src="x/x_drag.j s"></script> <script type="text/javascript" src="windows. js"X/script> <script type="text/javascript"

src="net.j s"></script> <script type="text/javascript"> window.onload=function(){

var pbar=document.getElementByld("planets"); var children=pbar.getElementsByTagName("div"); for(var i=O;i<children.length;i++){

Глава 5. Роль сервера в работе Ajax-приложения 203

// © Связывание с пиктограммами обработчиков событий

children[i].onclick=showlnfo;

J }

</script> </head> <body>

// 0 Включение пиктограмм, соответствующих планетам <div class="planetbar" id="planets">

<div class="planetbutton" id="mercury"> <img src="img/ball-mercury.gif"

alt="mercury"/> </div> <div class="planetbutton" id="venus"> <img src="img/ball-venus.gif" alt="venus"/>

</div> <div class="planetbutton" id="earth"> <img src="img/ball-earth.gif" alt="earth"/> </div> <div class="planetbutton" id="mars"> <img src="img/ball-mars.gif" alt="mars"/> </div> <div class="planetbutton" id="jupiter"> <img src="img/ball-jupiter.gif"

alt="jupiter"/> </div> <div class="planetbutton" id="saturn"> <img src="img/ball-saturn.gif" alt="saturn"/>

</div> <div class="planetbutton" id="uranus"> <img src="img/ball-uranus.gif" alt="uranus"/> </div> <div class="planetbutton" id="neptune"> <img src="img/ball-neptune.gif"

alt="neptune"/> </div> <div class="planetbutton" id="pluto"> <img src="img/ball-pluto.gif" alt="pluto"/>

</div> </div> </body> </html>

В состав нашего файла мы включили несколько JavaScript-библиотек О. Средства, предоставляемые net . js, обеспечивают поддержку низкоуровневых HTTP-запросов, используя для этой цели объект XMLHttpRequest, который обсуждался в главе 2. В файле windows, js определен объект окна, допускающего перетаскивание. Это окно мы используем для отображения информации. Детали реализации окна в данном случае не имеют значения; нас интересует только порядок вызова конструктора.

var MyWindow=new Window(bodyDiv,title,x,y, w,h);

где bodyDiv — это элемент DOM, который выводится в окне; t i t l e — строка, отображаемая в заголовке окна, а параметры х, у, w и h определяют начальные размеры окна. Задавая элемент DOM в качестве параметра, мы обеспечиваем достаточную гибкость при отображении данных к окне. Полностью код объекта Window можно скопировать с Web-узла, посвященного данной книге. Посредством HTML-кода, содержащегося в файле, мы определяем элемент div для каждой планеты ©, а в функции window.onload © связываем с пиктограммами планет обработчики onclick. В качестве обработчиков используются функции showlnf о (), которые в данном листинге не определены. В этой главе мы обсудим несколько вариантов их реализации. Рассмотрим Действия, которые мы можем предпринять тогда, когда нам требуется загрузка данных.

204 Часть II. Основные подходы к разработке приложений

Клиент

Рис. 5.7. Архитектура Ajax-приложения, ориентированная на содержимое. Клиент создает элемент IFrame и передает серверу запрос на получение информации. Содержимое генерируется моделью, представлением и контроллером уровня представления и возвращается элементу IFrame . На уровне клиента никакие требования к модели лредметной области не предъявляются

5.4.3. Взаимодействие, ориентированное на содержимое

Наши первые шаги по использованию подхода Ajax напоминают действия, которые предпринимаются при создании классического Web-приложения. В этом нет ничего удивительного; как было сказано в главе 1, в названии первых велосипедов присутствовало слово "лошадь". Взаимодействие, ориен-: тированное на содержимое, соответствует классическому подходу, но может иметь место и в Ajax-приложениях.

Общие сведения

При взаимодействии, ориентированном на содержимое, HTML-данные гене! рируются сервером и отображаются в составе элемента IFrame, включенного на главную Web-страницу. Элементы IFrame обсуждались в главе 2. Их можно определить в HTML-коде страницы или сгенерировать с помощью программы. При программной генерации мы получаем динамический интерфейс, а окно браузера напоминает оконный диспетчер. На рис. 5.7 условно показана архитектура, ориентированная на содержимое.

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

Листинг 5.2. Содержимое файла ContentPopup. j s

var offset=8;

function showlnfo(event){ var planet=this.id;

var infoWin=new ContentPopup( "info_"+planet+".html", planet+"Popup",

Глава 5. Роль сервера в работе Ajax-приложения 205

planet,offset,offset,320,320

);

offset+=32;

}

function'

ContentPopup(url,winEl,displayStr,x,y,w,h){ var bod=document.createElement("div") ; document.body.appendChild(bod);

this.iframe=document.createElement("iframe");

this.iframe.className="winContents";

this.iframe.src=url;

bod.appendChild(this.iframe);

this.win=new windows.Window(bod,displayStr,x,y,w,h);

}

_

Функция showlnf о () выполняет роль обработчика события для DOMэлемента, представляющего планету. В обработчике ссылка this указывает на элемент DOM. Чтобы определить, для какой из планет отображаются данные, используется идентификатор элемента.

Мы определили объект ContentPopup, который генерирует универсальный объект Window, создает элемент I Frame, предназначенный для просмотра содержимого, и загружает в него ресурс, определяемый URL. В данной ситуации мы лишь формируем имя статического HTML-файла и оформляем его в виде URL. В более сложном случае, если данные генерируются динамически, нам, возможно, придется добавить к URL строку параметров. Простой файл, предназначенный для отображения в составе iFrame (листинг 5.3), генерируется сервером.

Листинг 5.3. Содержимое файла info_earth.html

<html> <head>

 

<link rel=stylesheet type="text/css" href="../style.css"/>

 

</head>

 

<body class="info">

 

<div class="framedlnfo" id="info">

 

<div class="title" id="infotitle">earth</div>

 

<div class="content" id="infocontent">

 

A small blue planet near the outer rim of the galaxy,

 

third planet out from a middle-sized sun.

 

</div> </div> </body> </html>

В данном документе нет ничего примечательного: мы лишь используем обычный HTML-файл, как и для классического Web-приложения.

При использовании архитектуры, ориентированной на содержимое, клиенту требуется лишь ограниченная информация о бизнес-логике приложения, Достаточная для размещения элемента IFrame и формирования URL, определяющего содержимое для загрузки. Связь между клиентом и уровнем представления очень слабая; основная ответственность за предоставление содержимого возлагается на сервер. Преимущество данного типа взаимодействия состоит в том, что оно позволяет использовать готовые HTML-документы.