SOAP и Flash
Сервер, с которым я недавно работал, был написан на 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 очень просто разобраться.
И вот раскомментированный пример такого коннектора:
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); } } }
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 с вложениями, если они есть }
Всего комментариев 16
Комментарии
19.12.2012 21:46 | |
Цитата:
FlashBuilder тоже умеет генерировать код из wsdl.
|
19.12.2012 22:55 | |
Не знал, так как пользуюсь IDEA =) Возможно и умеет, просто я не в курсе.
|
23.12.2012 18:22 | |
Дайте ссылку на интересующий вас wsdl.
|
23.12.2012 19:05 | |
Уже не нужно, я FB поставил, сам сгенерировал и посмотрел эти ужасные портянки кода. На днях чуть допишу статью.
мы на "вы"? =) |
23.12.2012 19:08 | |
Цитата:
мы на "вы"? =)
Портянки будут везде, явные или неявные, хотя будут зависеть от средств языка и количества индусов в команде разработки генератора. |
23.12.2012 19:25 | |
Помимо этого, нужен еще свой SerializationFilter.
|
23.12.2012 19:32 | |
Пардон, с HttpService перепутал.
|
23.12.2012 19:46 | |
Да в принципе не сложно в коллбэки свою десериализацию ObjectProxy воткнуть и ручками вытаскивать данные.
IValueObject вот есть некий, ISOAPDecoder вообще нет такого. |
23.12.2012 21:09 | |
Последние записи от КорДум
- Basic authentication и GET/POST запросы (20.03.2013)
- SOAP и Flash (19.12.2012)
- Бинарные сокеты в AS3. Часть 3 (13.07.2012)
- Бинарные сокеты в AS3. Часть 2 (13.07.2012)
- Бинарные сокеты в AS3. Часть 1 (13.07.2012)