1

我在 AS3 中有需要压缩的 XML 数据,在我的 Java Google App Engine servlet 上进行验证,然后保存到 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 servlet 中接收它并创建文件:

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

这是我用来保存 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 回答
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 回答