МИНОБРНАУКИ РОССИИ «Санкт – Петербургский государственный электротехнический университет «ЛЭТИ» им. В.И. Ульянова (Ленина)» Кафедра ВТ Отчет Выполнил: Крапивин Е. А., факультет КТИ, группа № 6304 Проверил: Першин А. В. Санкт - Петербург 2010 г. Введение В данном отчете содержится информация по приложению на языке MXML для платформы Adobe Flex, представляющему собой клиентское приложение для гипотетического магазина. Приложение реализовано не в полном объеме из-за недоработок в серверной части. 1. Технология Flex Adobe Flex — технология для создания Rich Internet Applications. Flex — это основаная на Flash технология, предназначенная ускорить и упростить разработку насыщенных web-приложений. Flex расширяет базовые возможности flash, позволяя описывать интерфейс приложения на XML языке. Логика приложения пишется на ActionScript3. Результатом компиляции является SWF файл предназначеный для выполнения в браузере (На платформе Adobe Flash Player), или как самостоятельное приложение (на платформе AIR). Flex-приложение может компилироваться на сервере (для этого потребуется mod_flex.so или mod_flex.dll в зависимости от ОС и вебсервера), а может — из IDE или непосредственно из командной строки с помощью компилятора mxmlc (начиная с Flex 2), как и во Flash, результатом является файл swf, исполняемый в Flash Player. Flex — это большой набор классов, расширяющих возможности Flash. Flexframework включает возможности локализации, стилизации приложения, разработки модульного приложения, встроенные валидаторы и форматоры текстовых полей. Все те инструменты, которые нужны разработчикам приложений, работающих online. Но все готовые решения, включенные во Flex-framework, компилируются в результирующий SWF файл, увеличивая его размер. В случае с Flash результирующий SWF файл содержит только те классы, которые написал программист. Инструменты создания RIA основаны на flex-framework (Adobe Catalyst, Adobe Flex, Aptana Studio и т.д.). Инструменты для работы с анимацией и графикой используют базовые возможности flash. Поэтому баннеры и медийная реклама делаются без использования flex. 2. Технология WebServices Веб-служба, веб-сервис (англ. web service) — программная система, идентифицируемая строкой URI, чьи общедоступные интерфейсы определены на языке XML. Описание этой программной системы может быть найдено другими программными системами, которые могут взаимодействовать с ней согласно этому описанию посредством сообщений, основанных на XML, и передаваемых с помощью интернетпротоколов. Веб-служба является единицей модульности при использовании сервисориентированной архитектуры приложения. Существует несколько действующих стандартов веб-служб: XML, SOAP, WSDL, UDDI. К достоинствам веб-служб можно отнести обеспечение взаимодействия программных систем независимо от платформы; использование открытых стандартов и протоколов; простота разработки и отладки благодаря использованию XML; HTTPвзаимодействие программных систем через межсетевой экран благодаря использованию интернет-протокола. К недостаткам веб-служб относится меньшая производительность и больший размер сетевого трафика по сравнению с технологиями RMI, CORBA, DCOM за счёт использования текстовых XML-сообщений. Однако на некоторых Веб-серверах возможна настройка сжатия сетевого трафика. 3. Особенности работы клиентского приложения Настоящее приложение использует WSDL-реализацию веб-служб. Приложение реализует два веб-метода: запрос Категорий товаров (getTypes) и запрос Товаров (getGoods). Для корректной работы приложения как в тестовом режиме на локальной машине, так и на удаленном сервере, ему требуется xml-файл перекрестного домена. Файл содержит описания доменов, которым доступно использовать веб-службы и работу с сетью в общем в данном приложении. Файл должен называться crossdomain.xml и лежать в корне сайта. В случае использования локальной версии, запускаемой под веб-сервером Tomcat, файл должен лежать в папке ROOT каталога веб-приложений веб-сервера и содержать единственную запись хоста -- localhost. Работа с веб-службами проводится с проверкой сетевых ошибок. Контейнерами для приходящих данных являются компоненты DataGrid. Для корректного отображения данных, атрибуты dataField компонент DataGrid должны быть установлены в соответствующие поля, приходящие в объекте response от веб-службы. Для работы с веб-службами из клиента на технологии Flex необходимо сделать следующее: 1. Объявить переменную с типом WebService. 2. Инициализировать эту переменную, создав новой объект WebService. 3. Полю wsdl нового объекта необходимо указать полный путь к wsdl-документу. 4. Вызвать метод loadWSDL у объекта веб-службы (при этом опционально можно установить новый листенер событий ошибок работы с сетью). Чтобы выполнить запрос через веб-службу, необходимо: 1. Вызвать метод добавления листенера на событие удачного получения данных для объекта веб-службы с названием веб-метода (см. исходный код в части 6; по всей видимости, класс веб-службы объявлен динамическим, поэтому при загрузке wsdlдокумента доступные в нем методы становятся полями веб-службы автоматически) 2. Вызвать метод отправки данных поля объекта веб-службы с названием веб-метода. Чтобы получить данные от запроса и отобразить их, необходимо: 1. Создать компонент DataGrid и указать полям dataField ее столбцов символические названия параметров, которые отдает веб-служба (эти названия необходимо знать заранее). 2. При получении данных в метод листенера, их можно простым присваиванием отнести в компонент DataGrid. Для того чтобы клиент Flex запускался с удаленной машины, нужно корректно настроить сервер отдачи статических ресурсов. Для локальной отладки достаточно поместить swf-файл клиента в папку ROOT каталога webapps сервера Tomcat. 4. Запрос Категорий товаров Запрос не имеет параметров и получает список категорий товаров из таблицы st_types. Возвращаемые данные в объекте respose имеют два заголовка: id -идентификатор записи, сохраняется в скрытом столбце компонента dgCategories и description -- название категории. На рисунке 1 изображено успешное получение данных с сервера. Рисунок 1 - Результат выполнения запроса getTypes. 5. Запрос Товаров Запрос имеет один параметр -- тип категории, из которой требуется выбрать все товары. Возвращаемые данные в объекте respose имеют несколько заголовков, среди отображаемых -- price (цена товара за штуку), manufacturer (название изготовителя) и title (собственно, название товара). Еще один заголовок id скрыт аналогично пункту 4. На рисунке 2 изображено гипотетически успешное получение данных с сервера -- серверная часть реализована не в полной мере. Рисунок 2 - результат выполнения запроса getGoods. 6. Исходный текст клиентского приложения <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="700" height="500" initialize="init()"> <fx:Script> <![CDATA[ import mx.binding.utils.ChangeWatcher; import mx.controls.Alert; import mx.events.IndexChangedEvent; import mx.rpc.Fault; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.rpc.soap.LoadEvent; import mx.rpc.soap.WebService; private var webService:WebService; private var selectedCategoryTitle:String; private var selectedCategoryId:String; private function init(): void { viewstack.selectedChild = viewIntro; webService = new WebService(); webService.wsdl="http://localhost:8080/storage/services/main?wsdl"; webService.addEventListener(FaultEvent.FAULT, onCommonFault); webService.loadWSDL(); } private function onCommonFault(event:FaultEvent):void { var errorStr:String; errorStr = "Произошла ошибка при вызове веб-сервиса\n(\""; errorStr += event.fault.faultString; errorStr += "\")"; Alert.show(errorStr, "Ошибка сети"); } private function ongetTypesResult(event:ResultEvent):void { dgCategories.dataProvider = event.result; } private function ongetGoodsResult(event:ResultEvent):void { dgGoods.dataProvider = event.result; } protected function viewstack_changeHandler(event:IndexChangedEvent):void { switch(viewstack.selectedChild) { case viewTypes: { webService.getTypes.addEventListener(ResultEvent.RESULT, ongetTypesResult); webService.getTypes.addEventListener(FaultEvent.FAULT, onCommonFault); webService.getTypes.send(); break; } case viewGoods: { labelGoods.text = "А в категории \"" + selectedCategoryTitle + "\" мы имеем:"; webService.getGoods.addEventListener(ResultEvent.RESULT, ongetGoodsResult); webService.getGoods.addEventListener(FaultEvent.FAULT, onCommonFault); webService.getGoods.send(selectedCategoryId); break; } default: break; } } protected function button1_clickHandler(event: MouseEvent):void { viewstack.selectedChild = viewTypes; } protected function button2_clickHandler(event:MouseEvent):void { if(dgCategories.selectedItem == null) return; selectedCategoryTitle = dgCategories.selectedItem.description; selectedCategoryId = dgCategories.selectedItem.id; viewstack.selectedChild = viewGoods; } protected function button3_clickHandler(event:MouseEvent):void { viewstack.selectedChild = viewTypes; } ]]> </fx:Script> <fx:Declarations> </fx:Declarations> <mx:ViewStack x="25" y="32" id="viewstack" width="642" height="452" change="viewstack_changeHandler(event)"> <mx:Canvas id="viewIntro" label="viewIntro" width="100%" height="100%"> <s:Label x="180" y="206" text="Добро побаловать в наш магазин!" fontFamily="Times New Roman" fontSize="20"/> <s:Label x="242" y="233" text="Жмакните на кнопку ниже"/> <s:Button x="273" y="357" label="К категорям" click="button1_clickHandler(event)"/> </mx:Canvas> <mx:Canvas id="viewTypes" label="viewTypes" width="100%" height="100%"> <s:Label x="10" y="10" text="Мм. Посмотрим-ка, что у нас есть:" fontSize="14"/> <s:Label x="10" y="32" text="Выберите пункт и воткните кнопку ниже."/> <mx:DataGrid id="dgCategories" x="10" y="52" width="622" height="355"> <mx:columns> <mx:DataGridColumn visible="false" dataField="id"/> <mx:DataGridColumn headerText="Категории товаров" dataField="description"/> </mx:columns> </mx:DataGrid> <s:Button x="554" y="421" label="К товарам" click="button2_clickHandler(event)"/> </mx:Canvas> <mx:Canvas id="viewGoods" label="viewGoods" width="100%" height="100%"> <s:Label x="10" y="10" text="А в категории &quot;&quot; мы имеем:" fontSize="14" id="labelGoods"/> <mx:DataGrid id="dgGoods" x="10" y="49" width="622" height="351"> <mx:columns> <mx:DataGridColumn headerText="Название" width="200"/> <mx:DataGridColumn headerText="Продавец" dataField="description" width="250"/> <mx:DataGridColumn headerText="Цена" dataField="price"/> </mx:columns> </mx:DataGrid> <s:Button x="10" y="421" label="К категориям" click="button3_clickHandler(event)"/> </mx:Canvas> </mx:ViewStack> </mx:Application> 7. TODO Ввиду некоторой неочевидности в соответствии реализаци веб-служб в Java и Flex некоторые веб-службы требуют пересмотра архитектуры. В частности, существуют проблемы с отправкой запроса в веб-службу с неопределенным количеством параметров. Кроме того, нет возможности указывать именованные параметры при передаче их в запрос.