如何通过 Java 将二进制数据从 AS3 发送到文件系统?
我在 AS3 中有需要压缩的 XML 数据,在我的 Java Google App Engine servlet 上进行验证,然后保存到 Google Cloud Storage 中的文件中.稍后,该文件将由 AS3 客户端打开并解压缩.如果我使用纯 XML 或文本执行此过程,则该过程有效,但如果我使用 ByteArray#compress 数据,它会在 ByteArray#uncompress 期间因解压缩数据时出错"而死.
I've got XML data in AS3 that needs to be compressed, validated on my Java Google App Engine servlet then saved to a file in Google Cloud Storage. Later that file will be opened and decompressed by the AS3 client. The process works if I do it with plain XML or text, but if I ByteArray#compress the data, it dies during ByteArray#uncompress with "There was an error decompressing the data".
我尝试在不同的点设置内容类型和 mime 类型,以及使用 Base64 进行编码,但每次尝试似乎都以不同的方式中断,我再也没有收到与我发送的相同的 XML.我需要使用多部分?我应该在服务器上压缩吗?这样做的最佳做法是什么?
I've tried setting the content type and mime type at various points, as well as encoding with Base64, but every attempt seems to break in a different way and I never get the same XML back that I sent in. Do I need to use multipart? Should I compress on the server? What's the best practice for doing this?
从 AS3 发送数据:
Sending the data from 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 中接收并创建文件:
Receiving it in the Java servlet and creating the file:
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 中打开新文件:
Opening the new file in 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);
}
推荐答案
如果来自客户端,我会在 POST 之前进行 base64 编码,以这种方式存储在 TextProerty 中,然后在客户端收到返回时进行 base64 解码/解压缩.如果你想将它作为二进制存储在 GAE 上,那么 base64 将它解码成一个 Blob.以下是我使用您的代码拼凑的一些代码片段,以及我使用 HttpService 所做的类似事情——提前道歉,因为没有进行广泛的校对.HTH.
I would base64 encode before you POST if from the client, store it that way in a TextProerty, then base64 decode / decompress when received back at the client. If you want to store it as binary on GAE, then base64 decode it into a Blob. Here are some code snippets I pieced together using your code, and something similar I do using HttpService -- apologies in advance for not extensively proofing it. 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);
}
相关文章