Здесь, в SitePoint, есть немало учебников, которые помогут вам понять некоторые из ключевых принципов создания многофункциональных интернет-приложений (RIA) с использованием Flex и AIR. Вы обнаружите, что большинство разработок во Flex будет включать в себя фоновое приложение для взаимодействия с клиентом Flex.
Давайте обсудим некоторые теории и принципы, из которых состоит приложение Flex, а затем применим эти принципы на практике с помощью приложения ColdFusion. Здесь мы предполагаем, что у вас уже есть опыт разработки ColdFusion.
Обратите внимание, потому что в конце есть тест. Благодаря нашему спонсору, Adobe, первые 100 человек, прошедших тест, получат копию « Начало работы с Flex 3» . Пройди тест!
Понимание архитектуры насыщенного интернет-приложения
С точки зрения высокого уровня, общая системная архитектура веб-приложения обычно состоит из трех уровней.
Нижний уровень состоит из уровня хранения данных, обычно системы реляционных баз данных, такой как Microsoft SQL Server, Oracle или MySQL. Такой уровень обеспечивает модель реляционной таблицы, которую можно использовать для хранения и извлечения данных приложения.
Уровень выше уровня хранения данных называется сервером приложений или промежуточным программным обеспечением. На этой площадке обычно используются технологии Adobe ColdFusion, Java, PHP, Ruby on Rails или .NET. Эти платформы используются для разработки бизнес-логики и логики доступа к данным.
Помимо этого, или, возможно, даже встроенного в промежуточное ПО, мы найдем слой, отвечающий за доставку HTTP — то есть веб-серверы, такие как IIS или Apache. В насыщенных интернет-приложениях архитекторам иногда приходится иметь дело с другими протоколами, кроме HTTP: такие технологии, как Flash Media Server, например, поддерживают протокол потоковой передачи в реальном времени RTMP.
В моем предыдущем уроке я показал, как приложение Flex может взаимодействовать с другими приложениями и данными на стороне клиента. На этот раз мы теперь будем общаться с нашими уровнями бизнеса и данных на стороне сервера.
Как Flex связывается
Flex может получать доступ к удаленным данным в основном тремя различными способами:
- HTTP-вызовы плоских файлов, XML-файлов или динамических URL-адресов, которые доставляют данные, с которыми может работать Flex
- SOAP-вызовы веб-сервисов
- Вызовы удаленных объектов в формате Action Message Format (AMF).
Каждый из этих методов представлен различными классами ActionScript и тегами MXML. Справедливо сказать, что синтаксис тегов MXML, вероятно, проще использовать, если исходить из фона ColdFusion, потому что вы можете использовать синтаксис, аналогичный синтаксису ColdFusion CFML.
HTTPService: получение данных по HTTP
Давайте подумаем о теге mx:HTTPService
. Неудивительно, что это служба на основе HTTP, которую мы можем использовать для получения некоторых данных из других мест во время выполнения. В MXML такой сервис будет объявлен так:
<mx:HTTPService id="dataService" url="http://www.example.com/xmlfile.xml" />
Атрибут id
предоставляет ссылку на объект службы. Атрибут url
указывает на статический файл XML, который доступен через HTTP, но может также указывать на локальный файл, например:
<mx:HTTPService id="dataService" url="xmlfile.xml" />
В этом случае приложение Flex ожидает найти файл XML по тому же пути, что и сам.
Естественно, что ColdFusion может генерировать для нас какой-то XML. Вот очень простой способ сделать это:
<cfsavecontent variable="xmlContent"><data> <result> <item>Taxes</item> <amount>2000</amount> </result> ... </data></cfsavecontent> <cfcontent reset="true" type="text/xml"><cfoutput>#xmlContent#</cfoutput>
Тег хранит созданный статический или динамический контент в переменной xmlContent
. Затем мы используем тег cfcontent
для сброса любого вывода, который мы могли создать ранее, и указываем тип содержимого text/xml
. Затем мы доставляем содержимое переменной xmlContent
с помощью простого тега cfoutput
. Вуаля, выходит немного XML.
На следующей странице мы рассмотрим приложение Flex, которое будет использовать этот XML.
Приложение Flex для обслуживания такого вызова службы будет выглядеть следующим образом:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" creationComplete="cfmFile.send()"> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; import mx.collections.ArrayCollection; [Bindable] private var budgetData:ArrayCollection = new ArrayCollection(); private function cfmFileRH(e:ResultEvent):void { budgetData = e.result.data.result as ArrayCollection; } private function cfmFileFH(e:FaultEvent):void { mx.controls.Alert.show(e.fault.faultString,"Error when loading XML"); } ]]> </mx:Script> <mx:HTTPService id="cfmFile" url="http://example.com/budgetXML.cfm" result="cfmFileRH(event)" fault="cfmFileFH(event)" /> <mx:DataGrid dataProvider="{budgetData}" > </mx:DataGrid> </mx:Application>
Вот что происходит: мы используем mx:HTTPService
для получения некоторых данных и сохраняем результат от службы в переменной с именем budgetData
. Обработчик события creationComplete
для тега отправляет запрос HTTPService
при создании приложения. Наконец, объект mx:DataGrid
отображает данные в виде таблицы.
Если присмотреться к mx:HTTPService
мы увидим, что он включает в себя два атрибута: result
и fault
. Во Flex любой запрос службы данных обрабатывается асинхронно, что означает, что приложение Flex немедленно передает широковещательное событие, а не ожидает ответа. Все сервисные теги предлагают result
атрибутов и fault
чтобы иметь дело с любым из этих результатов. В этих атрибутах вы просто указываете имя метода, который вы хотите вызывать всякий раз, когда результат (или ошибка) возвращается после вызова службы.
Практически говоря, экземпляр mx:HTTPService
ограничен запросами GET
и POST
, хотя в принципе могут быть выполнены другие запросы, но они недоступны, если запросы HTTP не маршрутизируются через прокси-сервер, такой как Adobe BlazeDS или LiveCycle Data Services. , Причиной такого ограничения является модель безопасности Flash Player, которая поддерживает только прямые вызовы GET
или POST
через HTTP. Вот где в игру вступает другая концепция: файл междоменной политики.
Обычно приложение на основе Flash, использующее mx:HTTPService
или веб-службу на основе SOAP, может извлекать данные только из службы или файла, хранящегося на том же сервере, что и файл .swf. Чтобы определить, извлекаются ли данные из одного и того же домена, проигрыватель Flash Player сравнивает имена доменов, используемые для файла Flash и удаленного источника данных. Это означает, что приложение, загруженное с http: //localhost/test.swf, не может получить доступ к данным HTTP с http://127.0.0.1/data/xmlfile.xml — даже если они являются одним и тем же сервером. Одним из решений является использование файла междоменной политики с именем crossdomain.xml, размещенного в корневом веб-каталоге сервера, который предназначен для предоставления данных. Вы можете узнать больше о том, как использовать файл междоменной политики, в документации Adobe .
Далее давайте узнаем об отправке параметров запроса во Flex.
Параметры запроса на отправку
Возможно, вам нужно отправить параметры к вашему сервису. Самый простой способ передать параметры — это добавить тег mx:request
в качестве вложенного тега службы HTTP. Давайте представим, что нам нужно отправить два параметра, dataMethod
и userType
, в скрипт ColdFusion. Мы бы использовали элемент mx:request
так:
<mx:HTTPService id="dataService" url="http://example.com/sendDataRequest.cfm" method="POST"> <mx:request> <dataMethod>getAll</dataMethod> <userType>administrator</userType> </mx:request> </mx:HTTPService>
Поскольку мы используем метод HTTP POST
, все переменные запроса, которые мы здесь создаем, станут переменными ColdFusion в области видимости ColdFusion FORM
. Поэтому на стороне ColdFusion мы собираемся использовать FORM.dataMethod
а также FORM.userType
в шаблоне ColdFusion. Если бы вы выбрали HTTP GET
(указав method="GET"
), ваши данные запроса станут переменными URL: в этом случае URL.userType
и URL.dataMethod
.
До сих пор мы только что рассмотрели возврат XML-данных через HTTP-сервисы из шаблонов ColdFusion. Хотя это очень распространенный способ взаимодействия со службами HTTP и ColdFusion, существуют некоторые другие альтернативные форматы возврата для служб HTTP, которые в некоторых случаях могут быть более подходящими для использования:
-
object
: данные ответа являются XML и будут преобразованы в дерево объектов ActionScript (ArrayCollection
,ObjectProxy
) - Данные
xml
: response представляют собой XML и будут преобразованы в объект ActionScript типаXMLnode
— это устаревший формат, который используется только для совместимости; Лучше избегать его использования. -
e4x
: данные ответа являются XML и будут преобразованы в объект ActionScript XML -
flashvars
: данные ответа представляют собой цепочку пар ключ / значение:name1=value1&'name2=value2
и т. д. -
text
: данные ответа — текст, конверсия не происходит.
resultFormat="object"
- это значение по умолчанию, и зачастую это правильный путь. Если вы хотите работать с XML вместоArrayCollections
иObjectProxy
,e4x
(ECMAScript для XML) является предпочтительным форматом результата -xml
использует устаревший набор классов API, который является частью Flex только для совместимости.Предоставление услуги с ColdFusion
Итак: мы провели большую часть этой статьи, рассказывая о HTTP-сервисах и общей структуре сервиса. Теперь, когда мы понимаем, как они работают, обсуждение веб-сервисов и удаленных объектов становится намного проще.
Давайте возьмем следующий компонент ColdFusion, который предлагает один простой метод
echo
для внешнего мира, и попробуем встроить клиента Flex, который подключается к этому CFC:<cfcomponent>x <cffunction name="echo" returntype="string" access="remote" output="false" hint="I echo whatever I'm being passed"> <cfargument name="input" type="string" required="true"> <cfreturn "Echoing..." & arguments.input> </cffunction> </cfcomponent>
ColdFusion предлагает два способа представления функциональности метода этого компонента вызывающей стороне: в виде веб-службы на основе SOAP или в качестве удаленного объекта. Давайте попробуем каждый.
МЫЛО
Начиная с веб-службы SOAP, мы сделали метод echo методом веб-службы, установив атрибут
access="remote"
в тегеcffunction
. В то же время этот параметр позволит нам вызывать метод как удаленный объект. Мы хотели бы получить данные в формате WSDL, что можно сделать, просто добавив?WSDL
в конец URL.Чтобы получить этот WSDL во Flex, мы начнем с использования
mx:WebService
, структура которого во многом аналогичнаmx:HTTPService
:<mx:WebService id="dataWS" wsdl="http://example.com/service.cfc?WSDL" result="onDataServiceResult(event)" fault="onDataServiceFault(event)" />
С веб-сервисами вы часто обнаружите, что сервис предлагает несколько методов, и вы предпочитаете указывать метод обработки результата или ошибки для каждой службы. Это возможно при использовании
mx:operation
:<mx:WebService id="dataWS" wsdl="http://example.com/service.cfc?WSDL" fault="onDataServiceFault(event)" > <mx:operation name="echo" result="onResultEcho(event)" /> </mx:WebService>
Предоставление параметров для вызовов веб-службы работает аналогично предоставлению параметров для вызовов службы HTTP - через
mx:request
- но также может быть выполнено с использованием синтаксиса, знакомого разработчикам из языков, таких как Java или C ++:dataWS.echo("Hello")
Формат сообщения действия
Теперь давайте попробуем это с форматом сообщения действия (AMF). AMF - это протокол, который существует довольно давно, и спецификация AMF3 была публично выпущена Adobe в декабре 2007 года. На стороне сервера вам понадобится служба с поддержкой AMF3 - к счастью, как разработчик ColdFusion, вы готовы предоставить этот вид услуг прямо из коробки.
Во Flex мы можем использовать тег
mx:RemoteObject
для взаимодействия с удаленными объектами:<mx:RemoteObject id="dataRS" destination="ColdFusion" source="example.service"> <mx:method name="echo" result="onResultEcho(event)" fault="onFaultEcho(event)" /> </mx:RemoteObject>
Сравнивая этот код с эквивалентным объявлением веб-службы во Flex, мы обнаруживаем несколько небольших различий: мы имеем дело с местом назначения с именем «ColdFusion», и
mx:operation
поменялась наmx:method
.Когда кто-то сначала настраивает проект Flex для ColdFusion в Flex Builder, мастер установки задаст несколько вопросов, касающихся расположения сервера ColdFusion, его порта, URL-адреса и корневого контекста. Затем предоставленная информация будет использоваться во время компиляции приложения Flex, чтобы предоставить Flex сведения о URL-адресе AMF. Это работает плавно и легко для простых типов данных, таких как строки или логические значения, или даже для встроенных типов ColdFusion, таких как массивы и структуры.
Возможно, вы даже захотите работать с целыми объектами из бизнес-домена вашего приложения и передавать их туда и обратно. Существует шаблон проектирования, называемый объектом передачи данных или объектом значения, который описывает такой процесс, и его довольно просто использовать с компонентами ColdFusion. Ваша конфигурация сервиса во Flex в основном останется прежней, но вместо отправки или ожидания простых типов от вызова удаленного объекта это будет объект домена: объект, представляющий покупателя, корзину, сотрудника или все, что вы планируете иметь дело с. Чтобы позволить Flex иметь дело с такими сложными типами объектов, ColdFusion также должен знать о них, и в ColdFusion должен быть эквивалентный компонент. Вот CFC, который описывает пользователя:
<cfcomponent displayname="User" output="false"> <cfproperty name="user_id" type="numeric" /> <cfproperty name="user_name" type="string" /> <cffunction name="init" access="public" returntype="example.User" output="false"> <cfargument name="user_id" type="numeric" required="false" /> <cfargument name="user_name" type="string" required="false" /> <cfset this['user_id'] = arguments.user_id /> <cfset this['user_name'] = arguments.user_name /> <cfreturn this /> </cffunction> </cfcomponent>
В следующем минимальном классе ActionScript 3 мы также опишем, что должен содержать объект User:
[Bindable] [RemoteClass(alias="example.User")] public class User { public var user_id:int=0; public var user_name:String=""; }
Тег метаданных
[Bindable]
позволяет использовать пользователя в привязках данных Flex.[RemoteClass(alias="example.User")]
сопоставляет тип CFCexample.User
на стороне сервера с классомUser
здесь в ActionScript.Что теперь?
Куда мы отправимся отсюда? Если вы используете только ColdFusion, я предполагаю, что вам будет проще использовать RemoteObjects для подобных проектов. Если у вас смешанная среда, состоящая из нескольких технологий, возможно, стоит поискать веб-службы и вызовы службы HTTP для загрузки XML. В любом случае, вы теперь готовы справиться с любой ситуацией: время повеселиться!
Думаешь, ты готов нанести удар ColdFusion? Почему бы не проверить свои новые знания с помощью нашего теста - всего пять простых вопросов, и все ответы были прямо здесь, в этой статье. Первые 100 человек, принявших участие в нашей викторине, получат экземпляр « Getting Started with Flex», доставленный прямо к вашей двери абсолютно бесплатно. Хватай свою!