« mx.utils.Base64Encoder | Home | あ゙~~~~! »

Apr 112008

ByteArrayで変数をサーバに送信するの巻

apeirophobia: mx.utils.Base64Encoderでバタバタやっていましたが、nutsuさんのお力添えもあり、無事実装できましたので一応ご報告。

TASK
URLVariablesの中に普通のString等と一緒にByteArrayで構造化した情報を突っ込んで送ることができるか?またそれをサーバから再度読み込んで復元できるか?

PROCESS
1)Base64エンコーダを探すの巻
ByteArrayの送信の際にBase64でエンコードする必要があるので、その辺のクラスを探してみる。corelibのSHA256クラスの中とかにmx.utils.Base64Encoderというクラスの存在が確認できるのだが、そんなものはどこにも無い。ということで最初はhttp://crypto.hurlant.com/のcom.hurlant.util.Base64クラスを使って実装。一応これでも動く。
ただし開発が去年で停止しているのとcorelibの中にもcryptoパッケージが移植されているので、できればmx.utils.Base64Encoderで実装してみたいということでモソモソしてみる。

2)Base64Decoderでエラーが出るの巻
nutsuさんからFlex3 SDKの中に入っているという情報を頂き、喜び勇んでゲット。しかしvar bde:Base64Decoder = new Base64Decoder();を行うと

Error: No class registered for interface 'mx.resources::IResourceManager'.
at mx.core::Singleton$/getInstance()
at mx.resources::ResourceManager$/getInstance()
at mx.utils::Base64Decoder()
at test_PostPlay_fla::MainTimeline/frame1()
が表示され動作しない。

3)Base64Decoderのエラーを回避するの巻
nutsuさんの環境では動作するということでしばらくググッてhttp://bugs.adobe.com/jira/browse/SDK-12205#action_178148に到達。
ということで以下のスクリプトを追記。

import mx.core.Singleton;
var resourceManagerImpl:Object =
flash.system.ApplicationDomain.currentDomain.getDefinition("mx.resources::ResourceManagerImpl");
Singleton.registerClass("mx.resources::IResourceManager", Class(resourceManagerImpl));
これでエラーは出なくなった。

4)完成の巻
ということで完成したObjectをbyteArrayしてURLVariablesに突っ込んで送信するスクリプトは以下のような感じ。

import flash.utils.ByteArray;
import flash.net.*;
import flash.events.Event;
import mx.utils.Base64Encoder;
import mx.utils.Base64Decoder;
import mx.core.Singleton;
var resourceManagerImpl:Object =
flash.system.ApplicationDomain.currentDomain.getDefinition("mx.resources::ResourceManagerImpl");
Singleton.registerClass("mx.resources::IResourceManager", Class(resourceManagerImpl));
//
btPost.addEventListener(flash.events.MouseEvent.CLICK,_post);
btPost.buttonMode=true;
//
var data1:Object = {};
var data2:Object = {};
for (var i=0; i<20; i++) {
	data1[i] = {name:"あほあほまん"+i,year:i*i*i};
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(data1);
bytes.position = 0;
bytes.compress();
function _post(e) {
	var variables:URLVariables = new URLVariables();
	variables.name ="aho";
	variables.year="100";
	var enc:Base64Encoder = new Base64Encoder();
	enc.encodeBytes(bytes);
	variables.history = enc.flush();
	var request:URLRequest = new URLRequest();
	request.url = txPostTo.text;
	request.url = decodeURI("../tozaki/data2.dat");
	request.method = URLRequestMethod.POST;
	request.data = variables;
	var loader:URLLoader = new URLLoader();
	loader.dataFormat = URLLoaderDataFormat.VARIABLES;
	loader.addEventListener(Event.COMPLETE, completeHandler);
	try {
		loader.load(request);
	} catch (err) {
		trace("error",err);
	}
	//trace(request.data);
	//checkVar(request.data.history);
}
function completeHandler(e) {
	if (e.target.data.history) {
		checkVar(unescape(e.target.data.history));
	}
}
function checkVar(encodedText) {
	var dec:Base64Decoder = new Base64Decoder();
	dec.decode(encodedText);
	try {
		var byte:ByteArray = dec.flush();
	} catch (err) {
		trace(err);
	}
	byte.uncompress();
	byte.position = 0;
	data2 = byte.readObject();
	for (var i in data2) {
		trace(data2[i].name,data2[i].year);
		txOut.appendText("name="+data2[i].name+" / id="+data2[i].year+"\n");
	}
}
ちなみにByteArrayのzlib圧縮をかけた場合とかけない場合のデータの差は以下のような感じ。 1)compressあり

name=aho&history=eNp10K1OA2EQheEOM0zYRVdxAQ2q%2B%2B3%2FupUkvQBaWdEEAwKHQOwGQkKCIE1NVVVdZRUJN7M3wkHU%0A9Zgx5zHzxteiSSzR0%2FJx5ZOh64fu53R%2Fh36dRC%2Br5bONREMsF%2BdEcBPRlKyp25VoRtbM7UY0J2vu%0A1ooWZC3cXkVLspZu3Vy0InPl1t%2BL1mSu3d7wckPmxu19IZch%2Bd9vzyRJ3D4eAAIDiPaZAaQMoNtX%0AC5AxgHTfY4CcAdTb1AAFAwi4nQKUDKDhbgRQMYCK%2BwBQM4COhzuAhgGUPM5E%2FgAfkRQ5&year=100

2)compressなし

name=aho&history=CgsBAzAKAQluYW1lBifjgYLjgbvjgYLjgbvjgb7jgpMwCXllYXIEAAEDMQoBAgYn44GC44G744GC%0A44G744G%2B44KTMQYEAQEDMgoBAgYn44GC44G744GC44G744G%2B44KTMgYECAEDMwoBAgYn44GC44G7%0A44GC44G744G%2B44KTMwYEGwEDNAoBAgYn44GC44G744GC44G744G%2B44KTNAYEQAEDNQoBAgYn44GC%0A44G744GC44G744G%2B44KTNQYEfQEDNgoBAgYn44GC44G744GC44G744G%2B44KTNgYEgVgBAzcKAQIG%0AJ%2BOBguOBu%2BOBguOBu%2BOBvuOCkzcGBIJXAQM4CgECBifjgYLjgbvjgYLjgbvjgb7jgpM4BgSEAAED%0AOQoBAgYn44GC44G744GC44G744G%2B44KTOQYEhVkBBTEwCgECBinjgYLjgbvjgYLjgbvjgb7jgpMx%0AMAYEh2gBBTExCgECBinjgYLjgbvjgYLjgbvjgb7jgpMxMQYEijMBBTEyCgECBinjgYLjgbvjgYLj%0Agbvjgb7jgpMxMgYEjUABBTEzCgECBinjgYLjgbvjgYLjgbvjgb7jgpMxMwYEkRUBBTE0CgECBinj%0AgYLjgbvjgYLjgbvjgb7jgpMxNAYElTgBBTE1CgECBinjgYLjgbvjgYLjgbvjgb7jgpMxNQYEmi8B%0ABTE2CgECBinjgYLjgbvjgYLjgbvjgb7jgpMxNgYEoAABBTE3CgECBinjgYLjgbvjgYLjgbvjgb7j%0AgpMxNwYEpjEBBTE4CgECBinjgYLjgbvjgYLjgbvjgb7jgpMxOAYErUgBBTE5CgECBinjgYLjgbvj%0AgYLjgbvjgb7jgpMxOQYEtUsBAQ%3D%3D&year=100

改行というか空白が入っている分データは大きいのかな?良く分からない。ちなみにcompressかけなくてもdecordeの際にuncompressしないとなんかな「RangeError: Error #2006: 指定したインデックスが境界外です。」なエラーが出てくる。理由は不明。

ちょっとまだサーバサイドでDBに格納してないのであれですが、多分いけるのではないかと・・。

nutsuさん色々とありがとうございました!!

3 Comments

うお・・めっちゃ横に伸びとる・・・orz

どうもです。
僕の環境でエラーが発生しなかったのはSDKのビルドの違いだったようです。
昨日テストしたのはBeta3でした。最新の3.0.477を入れてみたら、無事に?同じエラー出てます…。
中途半端な情報で申し訳なかったです。

いえいえ、こちらこそ色々とありがとうございました!

Leave a comment

Search and Archives