Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > КорДум

Оценить эту запись

SOAP и Flash

Запись от КорДум размещена 19.12.2012 в 19:03
Обновил(-а) КорДум 19.12.2012 в 19:40

Сервер, с которым я недавно работал, был написан на PHP и предоставлял свои RPC-методы, отсылая и принимая избыточные SOAP, а если точнее, WSDL документы с SOAP-данными в качестве ответов. Первоначально сам наш клиент-проект состоял из нескольких приложений и общение с веб-сервисом проходило в программе, написанной на C#. Там коннектор к веб-сервису создается очень быстро мышью, добавляется через пару кликов, сразу же генерируются синхронные и асинхронные публичные методы, какие-то свои кастомные классы, экземпляры которых RPC-методы возвращают. Все было очень удобно: скармливаешь генератору URI до веб-сервиса, документ, описывающий все RPC-методы и возвращаемые данные, скачивается, коннектор генерируется, все довольны. И возможность использования синхронных методов или асинхронных тоже радовала.

Затем проект эволюционировал до одного приложения на AIR и все бы хорошо, но когда же я начал портировать все куски продукта на AS3, столкнулся с достаточно малым количеством информации по SOAP, откуда бы можно было сразу же писать код и не задумываться о кодировании уходящих и декодировании приходящих данных и прочем. В гугле нашлась парочка кастомных библиотек для работы, давно уже не поддерживающихся, но скудная документация на давно устаревших страницах не внушала доверия и поиск продолжался. Вскоре нашлась информация о "родной" FlexSDK'шной библиотеке. Живет она в пакете mx.rpc и почему-то при подключении SDK к проекту не подхватывается автоматически, хотя в списке подхваченных SWC значилась, чему я неприятно удивился.

В общем, пришлось выдрать SWC из SDK и насильно подключить к проекту. Забегая чуть вперед, скажу, что придется выдрать еще и framework.swc, так как из него используются какие-то там классы. Сидят обе SWC вот по таким путям:
flexsdk/frameworks/libs/framework.swc
flexsdk/frameworks/libs/rpc.swc


А дальше все пошло как по маслу, в работе непосредственно WebService очень просто разобраться.
И вот раскомментированный пример такого коннектора:
Код AS3:
package shell.net {
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.soap.LoadEvent;
	import mx.rpc.soap.WebService;
 
	/**
	 * @author: KorDum
	 */
 
	public class SoapConnector {
		private var _web:WebService;
		private var _uri:String;
 
		private var _onFault:Function;
		private var _onFoo:Function;
 
		//---------------------------------------------------------------------------
		//
		// CONSTRUCTOR
		//
		//---------------------------------------------------------------------------
 
		public function SoapConnector() {
			_web = new WebService();
			_web.addEventListener(LoadEvent.LOAD, web_loadHandler);
			_web.addEventListener(FaultEvent.FAULT, web_faultHandler);
		}
 
 
		//---------------------------------------------------------------------------
		//
		// PRIVATE HANDLERS
		//
		//---------------------------------------------------------------------------
 
		private function web_loadHandler(event:LoadEvent):void {
			// возникает, когда загрузка WSDL-документа 
			// с описанием всех методов успешна
		}
 
 
		private function web_faultHandler(event:LoadEvent):void {
			// возникает, когда загрузка WSDL-документа 
			// с описанием всех методов завершилась неудачей
		}
 
 
		//---------------------------------------------------------------------------
		//
		// PUBLIC METHODS
		//
		//---------------------------------------------------------------------------
 
		public function start(uri:String):void {
			// "коннектимся" к веб-сервису
			// "инициализируем" коннектор
			// здесь вообще скачивается весь WSDL-документ со  всем RPC
			_web.loadWSDL(uri);
			_uri = uri;
		}
 
		/**
		 * Вызов RPC-метода foo с передачей параметров
		 * Предварительных инициализаций этого метода не нужно, 
		 * так как WebService динамический
		 */
		public function foo(param1:String, param2:uint):void {
			_web.foo(param1, param2);
		}
 
 
		//---------------------------------------------------------------------------
		//
		// PUBLIC ACCESSORS
		//
		//---------------------------------------------------------------------------
 
		public function get uri():String { return _uri; }
 
		/**
		 * Коллбэк возвращаемых ошибок RPC-методов
		 */
		public function get onFault():Function { return _onFault; }
		public function set onFault(value:Function):void {
			_onFault = value;
			_web.foo.addEventListener(FaultEvent.FAULT, value);
			// другие RPC-методы и подписка на событие FAULT
		}
 
 
		/**
		 * Коллбэк возвращаемого результата работы foo()
		 */
		public function get onFoo():Function { return _onFoo; }
		public function set onFoo(value:Function):void {
			_onFoo = value;
			_web.foo.addEventListener(ResultEvent.RESULT, value);
		}
	}
}
И пример коллбэка для метода foo():

Код AS3:
private function connector_fooHandler(event:ResultEvent):void {
	// для простых ответов
	var result:String = event.result.toString();
	// если возвращается массив каких-то кастомных экземпляров классов 
	// (или просто экземпляр кастомного класса)
	// то event.result будет is Object, у которого можно достать ключи и значения через
	// for (var key:String in event.result)
	// другими словами все сложные возвращаемые результаты будут is Object с вложениями, если они есть
}
Естественно, придется попросить товарища серверника предоставить все протоколы, чтобы знать, что именно передается в коллбэки и что нужно передавать в методы, ибо тут нет автогенерации, как в шарповой IDE.
Размещено в net
Комментарии 16 Отправить другу ссылку на эту запись
Всего комментариев 16

Комментарии

Старый 19.12.2012 21:39 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
Все было очень удобно: скармливаешь генератору URI до веб-сервиса, документ, описывающий все RPC-методы и возвращаемые данные, скачивается, коннектор генерируется, все довольны.
FlashBuilder тоже умеет генерировать код из wsdl.
Старый 19.12.2012 21:46 GBee вне форума
GBee
 
Аватар для GBee
Цитата:
FlashBuilder тоже умеет генерировать код из wsdl.
Раньше он это делал кривовато. Приходилось допиливать.
Старый 19.12.2012 22:55 КорДум вне форума
КорДум
 
Аватар для КорДум
Не знал, так как пользуюсь IDEA =) Возможно и умеет, просто я не в курсе.
Старый 20.12.2012 19:56 КорДум вне форума
КорДум
 
Аватар для КорДум
Кстати, можете показать итоговый класс коннектора, сгенерированного FB, с возвращаемым в каком-то коллбэке кастомным экземпляром класса? Мне интересно, есть ли "нативные" на уровне SDK средства для десериализации приходящего Object.
Старый 23.12.2012 18:22 alatar вне форума
alatar
 
Аватар для alatar
Дайте ссылку на интересующий вас wsdl.
Старый 23.12.2012 19:05 КорДум вне форума
КорДум
 
Аватар для КорДум
Уже не нужно, я FB поставил, сам сгенерировал и посмотрел эти ужасные портянки кода. На днях чуть допишу статью.
мы на "вы"? =)
Старый 23.12.2012 19:08 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
мы на "вы"? =)
Нет, конечно
Портянки будут везде, явные или неявные, хотя будут зависеть от средств языка и количества индусов в команде разработки генератора.
Старый 23.12.2012 19:16 КорДум вне форума
КорДум
 
Аватар для КорДум
Кстати, вот по портянке видно, что используют одну штуку, неосвещенную ни в одном мануале, что я находил:
Код AS3:
operation = new mx.rpc.soap.mxml.Operation(null, "Tasks");
operation.resultElementType = valueObjects.TerminalTask;
Возвращается ArrayCollection с экземплярами класса TerminalTask. Я сгенерированный пример не рискнул запустить, а вот в боевом проекте строчка с назначением возвращаемого типа не работает: все равно возвращаются экземпляры ObjectProxy, в результате чего приходится вытаскивать из обджекта все нужные поля вручную.
У тебя выходило сделать возвращение нужных экземпляров класса?
Старый 23.12.2012 19:25 alatar вне форума
alatar
 
Аватар для alatar
Помимо этого, нужен еще свой SerializationFilter.
Старый 23.12.2012 19:32 alatar вне форума
alatar
 
Аватар для alatar
Пардон, с HttpService перепутал.
Старый 23.12.2012 19:36 alatar вне форума
alatar
 
Аватар для alatar
Посмотри не генерируется ли там класс реализующий ISOAPDecoder.
По RPC вообще документация довольно скудна, проще в сразу в исходниках смотреть. Видимо рассчитывали, что все будут использовать генерацию и не париться.
Старый 23.12.2012 19:46 КорДум вне форума
КорДум
 
Аватар для КорДум
Да в принципе не сложно в коллбэки свою десериализацию ObjectProxy воткнуть и ручками вытаскивать данные.
IValueObject вот есть некий, ISOAPDecoder вообще нет такого.
Старый 23.12.2012 19:47 КорДум вне форума
КорДум
 
Аватар для КорДум
Я так понимаю, если использовать сгенерированное, там просто туча ненужных лишних действий, массивов, обджектов и прочего. Овчинка выделки не стоит. Даже если вернется какой-то шибко сложный объект, проще, вернее целесообразнее, будет руками его распарсить, чем использовать автогенерацию сомнительного качества.
Старый 23.12.2012 21:08 alatar вне форума
alatar
 
Аватар для alatar
Если парсить полученный результат, у тебя тоже получается куча лишних действий, если хочешь сам парсить, то проще использовать HTTPService, или вообще URLLoader. Кстати, отключи makeObjectsBindable и тебе будут приходить обычные Object.
Старый 23.12.2012 21:09 alatar вне форума
alatar
 
Аватар для alatar
Ты уверен, что там именно operation.resultElementType? У меня генерируется:
Код AS3:
operation.resultType = valueObjects.RegExpHostName;
Старый 23.12.2012 21:17 КорДум вне форума
КорДум
 
Аватар для КорДум
Цитата:
Кстати, отключи makeObjectsBindable и тебе будут приходить обычные Object
Вот это очень полезно.

Цитата:
Ты уверен, что там именно operation.resultElementType?
Это когда возвращается коллекция с чем-то. Для неколлекций resultType.
 

 


Часовой пояс GMT +4, время: 22:54.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.