воскресенье, 1 августа 2010 г.

BinaryHTTPService или как помочь HTTPService-у принимать ByteArray данные

В процессе разработки у меня стояла задача найти способ получать бинарные данные от сервера через HTTPService. Сам по себе HTTPService из пакета mx не позволяет получать результат в ByteArray. Это можно увидеть в классе mx.messaging.channels.DirectHTTPChannel в функции internalSend.



package mx.messaging.channels
{
public class DirectHTTPChannel extends Channel
{

.....

override protected function internalSend(msgResp:MessageResponder):void
{
var httpMsgResp:DirectHTTPMessageResponder = DirectHTTPMessageResponder(msgResp);
var urlRequest:URLRequest;

try
{
urlRequest = createURLRequest(httpMsgResp.message);
}
catch(e: MessageSerializationError)
{
httpMsgResp.agent.fault(e.fault, httpMsgResp.message);
return;
}

var urlLoader:URLLoader = httpMsgResp.urlLoader;
urlLoader.addEventListener(ErrorEvent.ERROR, httpMsgResp.errorHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, httpMsgResp.errorHandler);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, httpMsgResp.securityErrorHandler);
urlLoader.addEventListener(Event.COMPLETE, httpMsgResp.completeHandler);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpMsgResp.httpStatusHandler);
urlLoader.load(urlRequest);
}

.....

}
}


У URLLoader-а по умолчанию параметр dataFormat имеет значение URLLoaderDataFormat.TEXT, а для получения данных в виде ByteArray нужен URLLoaderDataFormat.BINARY.


Всё делается очень просто. Первое, что нам нужно – это создать расширение для класса DirectHTTPChannel и установить у urlLoader-а параметр dataFormat=URLLoaderDataFormat.BINARY;



public class DirectHTTPBinaryChannel extends DirectHTTPChannel
{
public function DirectHTTPBinaryChannel(id:String, uri:String="")
{
super(id, uri);
}

override protected function getMessageResponder(agent:MessageAgent,
message:IMessage):MessageResponder
{
return new DirectHTTPBinaryMessageResponder(agent, message, this, new URLLoader());
}

override protected function internalSend(msgResp:MessageResponder):void
{
var httpMsgResp:DirectHTTPBinaryMessageResponder = DirectHTTPBinaryMessageResponder(msgResp);
var urlRequest:URLRequest;

try
{
urlRequest = createURLRequest(httpMsgResp.message);
}
catch(e: MessageSerializationError)
{
httpMsgResp.agent.fault(e.fault, httpMsgResp.message);
return;
}

var urlLoader:URLLoader = httpMsgResp.urlLoader;
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(ErrorEvent.ERROR, httpMsgResp.errorHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, httpMsgResp.errorHandler);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, httpMsgResp.securityErrorHandler);
urlLoader.addEventListener(Event.COMPLETE, httpMsgResp.completeHandler);
urlLoader.load(urlRequest);
}
}


Для того, чтобы мы могли использовать наш DirectHTTPBinaryChannel, создаем расширение класса HTTPService.



public class BinaryHTTPService extends HTTPService
{
protected static var binaryChannel:Channel;
protected static var binaryChannelSet:ChannelSet;

public function BinaryHTTPService(rootURL:String = null, destination:String = null)
{
super(rootURL, destination);
}

override public function send(parameters:Object = null):AsyncToken
{
if (useProxy == false)
{
/* force the use of our binary channel */
if (binaryChannelSet == null)
{
var dcs:ChannelSet = new ChannelSet();
binaryChannel = new DirectHTTPBinaryChannel("direct_http_binary_channel");
dcs.addChannel(binaryChannel);
channelSet = dcs;
binaryChannelSet = dcs;
}
else if (channelSet != binaryChannelSet)
{
channelSet = binaryChannelSet;
}
}
return super.send(parameters);
}
}


Рабочие классы:

https://code.google.com/p/apron/source/browse/version_2/apron2_network/s...

https://code.google.com/p/apron/source/browse/version_2/apron2_network/s...

Комментариев нет:

Отправить комментарий