1

AS3 の XML データを圧縮し、Java Google App Engine サーブレットで検証してから、Google Cloud Storage のファイルに保存する必要があります。その後、そのファイルは AS3 クライアントによって開かれ、解凍されます。プレーンな XML またはテキストで実行するとプロセスは機能しますが、データを ByteArray#compress すると、ByteArray#uncompress 中に「データの解凍中にエラーが発生しました」というメッセージが表示されて終了します。

さまざまなポイントでコンテンツ タイプと MIME タイプを設定し、Base64 でエンコードしようとしましたが、試行ごとに異なる方法で壊れているようで、送信したものと同じ XML が返されません。使用する必要がありますか?マルチパート? サーバー上で圧縮する必要がありますか? これを行うためのベストプラクティスは何ですか?

AS3 からのデータの送信:

// compress xml using zlib
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();

var request:URLRequest = new URLRequest(url);
var urlVariables :URLVariables = new URLVariables();
urlVariables.filename = "somefile.bin";
urlVariables.contents = bytes;
request.data = urlVariables;
request.method = URLRequestMethod.POST;
loader = new URLLoader();
loader.load(request);

Java サーブレットでそれを受け取り、ファイルを作成します。

public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String filename = req.getParameter("filename");
    byte[] contents = req.getParameter("contents").getBytes();

    GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder()
        .setBucket("bucketname")
        .setKey(filename)
        .setAcl("public-read")
        .setMimeType("binary/octet-stream");
    AppEngineFile writableFile = fileService.createNewGSFile(optionsBuilder.build());
    boolean lockForWrite = true;
    FileWriteChannel writeChannel = fileService.openWriteChannel(writableFile, lockForWrite);
    writeChannel.write(ByteBuffer.wrap(contents));
    writeChannel.closeFinally();
}

AS3 で新しいファイルを開く:

var url :String = "http://commondatastorage.googleapis.com/bucketname/somefile.bin";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);

protected function handleComplete (event:Event):void {
    var bytes:ByteArray = new ByteArray();
    bytes.writeObject(event.target.data);

    // dies on this line with "There was an error decompressing the data."
    bytes.uncompress();

    var xml:XML = new XML(new String(bytes));
    trace(xml);
}
4

2 に答える 2

0

クライアントから POST する前に base64 エンコードし、そのように TextProerty に格納し、クライアントで受信したときに base64 デコード/解凍します。GAE にバイナリとして保存する場合は、base64 でデコードして Blob にします。ここに、あなたのコードを使用してつなぎ合わせたいくつかのコード スニペットと、HttpService を使用して同様のことを行います。広範囲にわたる検証を行っていないことを事前にお詫びします。HTH。

private var _serviceHttp:HTTPService = new HTTPService;

private function postBytes():void {
    var xml:XML = <contents><thing>value</thing></contents>;
    var bytes:ByteArray = new ByteArray();
    bytes.writeObject(xml);
    bytes.position = 0;
    bytes.compress();
    var enc:Base64Encoder = new Base64Encoder();
    enc.encodeBytes(bytes, 0, bytes.length);
    var myObj:Object = new Object();
    myObj["bytes"] = enc.toString();
    // myObj["other_variables"] = your_other_varaibles;
    _serviceHttp.method = "POST";
    _serviceHttp.resultFormat = "flashvars";
    _serviceHttp.url = your_url_here;
    _serviceHttp.addEventListener(ResultEvent.RESULT, urlHandler);
    _serviceHttp.addEventListener(FaultEvent.FAULT, urlErrorHandler);
    _serviceHttp.send(myObj);
}
于 2012-04-11T16:15:59.877 に答える
0

これは、xml を保存するために使用するコードです。データを PHP に送信しますが、同じように機能すると思います... 問題はありませんでした。

var createXMLURL:URLRequest = new URLRequest("createXML.php");
createXMLURL.method = URLRequestMethod.POST;
var Variables:URLVariables = new URLVariables();
Variables.xmlString = xml.toXMLString();
Variables.filename = filename;
createXMLURL.data = Variables;
var loader:URLLoader = new URLLoader();
loader.dataFormat = "VARIABLES";
loader.addEventListener(Event.COMPLETE, xmlCreated);
loader.load(createXMLURL);

宣言を含めなかったので、いくつかの変数が何であるかについて質問がある場合はお知らせください(それらは非常に簡単に理解できると思います)。

今、これはあなたが求めていたようにそのデータをバイナリ形式で送信しませんが、生のバイトが本当に必要な場合、Javaで受信すると文字列をバイナリに変換できない理由がわかりません。

于 2012-04-10T22:43:16.577 に答える