Java Spring MVC 将文件上传为 byte[]
我有以下问题。
我有一个用 C++/CLI 编写的 ActiveX 控件,我在客户端使用它。控制方法之一按固定块大小(例如按 1024)返回二进制文件。该文件已压缩。
我需要使用 C++/CLI 编写方法,将每个文件块发送到服务器。我有 Java Spring MVC 方法,它接收这个 byte[] 块并将其附加到文件中。换句话说,我只是按块上传 zip 文件。
我的问题是,虽然两个文件(原始文件及其在服务器上的副本)的文件大小不同,但该文件的 MD5 校验和不同,并且我无法使用 zip 打开该文件。文件已损坏。
我只是将每个块 byte[] 使用 BASE64 进行转换,然后使用常规 POST 请求将其发送到服务器:
我的代码如下:
int SceneUploader::AddChunk(int id, array<Byte> ^buffer,int size){
WebRequest^ request = WebRequest::Create(AddChunkURI);
request->Method = "POST";
request->ContentType = "application/x-www-form-urlencoded";
System::String ^base64Image = Convert::ToBase64String(buffer);
String ^param = "id="+id+"&chunk="+base64Image+"&len="+size;
//Just make another copy of the file to verify that sent byted are ok!!!
String ^path = "C:\\Users\\dannyl\\AppData\\Local\\Temp\\test.zip";
FileStream ^MyFileStream = gcnew FileStream(path, FileMode::Append, FileAccess::Write);
MyFileStream->Write(buffer,0,size);
MyFileStream->Close();
//Adding the byteArray to the stream.
System::IO::Stream ^stream = request->GetRequestStream();
System::IO::StreamWriter ^streamWriter = gcnew System::IO::StreamWriter(stream);
streamWriter->Write(param);
streamWriter->Close();
HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
Stream^ dataStream = response->GetResponseStream();
StreamReader^ reader = gcnew StreamReader( dataStream );
String^ responseFromServer = reader->ReadToEnd();
return System::Int32::Parse(responseFromServer);
}
我的 MVC 控制器如下所示:
@RequestMapping(value="/addChunk.dlp",method = RequestMethod.POST)
@ResponseBody
public String addChunk(@RequestParam("id") String id,
@RequestParam("chunk") String chunk,
@RequestParam("len") String len){
try{
BASE64Decoder decoder = new BASE64Decoder();
Integer length = Integer.decode(len);
byte[] decodedBytes = new byte[length];
decodedBytes = decoder.decodeBuffer(chunk.trim());
File sceneFile = new File(VAULT_DIR+id+".zip");
if (!sceneFile.exists()){
sceneFile.createNewFile();
}
long fileLength = sceneFile.length();
RandomAccessFile raf = new RandomAccessFile(sceneFile, "rw");
raf.seek(fileLength);
raf.write(decodedBytes);
raf.close();
}
catch(FileNotFoundException ex){
ex.getStackTrace();
System.out.println(ex.getMessage());
return "-1";
}
catch(IOException ex){
ex.getStackTrace();
System.out.println(ex.getMessage());
return "-1";
}
return "0";
}
我做错了什么?
更新:问题已解决。原始Base64字符串有'+'字符,请求提交到服务器后,块参数被Spring URL解码,所有'+'字符被空格替换,结果zip文件被损坏。请把我的+50 声望还给我:)
谢谢, 丹尼.
I have the following problem.
I have a ActiveX control written in C++/CLI, which I'm using on client side. one of the control method return binary file by fixed chunk size (for example by 1024). This file is zipped.
I need to write method using C++/CLI which will send each file chunk to the server. I have Java Spring MVC method which receives this byte[] chunk and append it to file. In other words I'm just uploading zip file by chunks.
My problem is, that although the file size of both files (Original and its copy on server) ,the MD5 checksum of this file is not the same and I can't open this file using zip. The file is corrupted.
I'm just taking each chunk byte[] convert it with BASE64 and send it to server using my regular POST request:
My code is the following:
int SceneUploader::AddChunk(int id, array<Byte> ^buffer,int size){
WebRequest^ request = WebRequest::Create(AddChunkURI);
request->Method = "POST";
request->ContentType = "application/x-www-form-urlencoded";
System::String ^base64Image = Convert::ToBase64String(buffer);
String ^param = "id="+id+"&chunk="+base64Image+"&len="+size;
//Just make another copy of the file to verify that sent byted are ok!!!
String ^path = "C:\\Users\\dannyl\\AppData\\Local\\Temp\\test.zip";
FileStream ^MyFileStream = gcnew FileStream(path, FileMode::Append, FileAccess::Write);
MyFileStream->Write(buffer,0,size);
MyFileStream->Close();
//Adding the byteArray to the stream.
System::IO::Stream ^stream = request->GetRequestStream();
System::IO::StreamWriter ^streamWriter = gcnew System::IO::StreamWriter(stream);
streamWriter->Write(param);
streamWriter->Close();
HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
Stream^ dataStream = response->GetResponseStream();
StreamReader^ reader = gcnew StreamReader( dataStream );
String^ responseFromServer = reader->ReadToEnd();
return System::Int32::Parse(responseFromServer);
}
My MVC controller looks like this:
@RequestMapping(value="/addChunk.dlp",method = RequestMethod.POST)
@ResponseBody
public String addChunk(@RequestParam("id") String id,
@RequestParam("chunk") String chunk,
@RequestParam("len") String len){
try{
BASE64Decoder decoder = new BASE64Decoder();
Integer length = Integer.decode(len);
byte[] decodedBytes = new byte[length];
decodedBytes = decoder.decodeBuffer(chunk.trim());
File sceneFile = new File(VAULT_DIR+id+".zip");
if (!sceneFile.exists()){
sceneFile.createNewFile();
}
long fileLength = sceneFile.length();
RandomAccessFile raf = new RandomAccessFile(sceneFile, "rw");
raf.seek(fileLength);
raf.write(decodedBytes);
raf.close();
}
catch(FileNotFoundException ex){
ex.getStackTrace();
System.out.println(ex.getMessage());
return "-1";
}
catch(IOException ex){
ex.getStackTrace();
System.out.println(ex.getMessage());
return "-1";
}
return "0";
}
What am I doing wrong?
Update: the problem solved. Original Base64 String had '+' characters, after the request was submitted to server the chunk parameter was URLdecoded by Spring and all'+' characters were replaced by spaces, as a result zip file was corrupted. Please give me back my +50 of reputation :)
Thank you,
Danny.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我还没有经历过你的客户端通过 HTTP 将文件发送到服务器的情况。
但是,在服务器端,您可以查看 Spring MVC 多部分。在客户端,使用 Multipart 发送文件是实现目标的另一种方法。
I have not experienced about your client-side for sending file to server with HTTP.
In server side, however, you may check out the Spring MVC Multipart. And in client side, sending file with Multipart is another way to achieve your goal.