2010-12-15 29 views
3

J'ai le problème suivant.Java Spring MVC télécharger le fichier comme octet []

J'ai un contrôle ActiveX écrit en C++/CLI, que j'utilise côté client. l'une des méthodes de contrôle renvoie le fichier binaire par taille de bloc fixe (par exemple par 1024). Ce fichier est compressé.

Je dois écrire une méthode en utilisant C++/CLI qui enverra chaque fragment de fichier au serveur. J'ai la méthode Java Spring MVC qui reçoit ce morceau byte [] et l'ajoute au fichier. En d'autres termes, je ne fais que télécharger un fichier zip par morceaux. Mon problème est que, bien que la taille du fichier des deux fichiers (Original et sa copie sur le serveur), la somme de contrôle MD5 de ce fichier n'est pas la même et je ne peux pas ouvrir ce fichier en utilisant zip. Le fichier est corrompu.

Je prends juste chaque octet de morceau [] convertir avec BASE64 et l'envoyer au serveur en utilisant ma demande régulière POST:

Mon code est le suivant:

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); 
} 

Mon contrôleur MVC regards comme ceci:

@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"; 
     } 

Qu'est-ce que je fais mal?

Mise à jour: le problème a été résolu. Original Base64 String avait '+' caractères, après que la requête a été soumise au serveur, le paramètre chunk a été codé en URL par Spring et tous les caractères '+' ont été remplacés par des espaces, par conséquent le fichier zip a été corrompu. Veuillez me rendre mon +50 de réputation :)

Merci, Danny.

+0

Le mot «C++» a été remplacé par «C++/CLI». Malgré la syntaxe similaire dans de nombreux endroits, ce sont vraiment des langues différentes; C++/CLI a plus en commun avec C# qu'avec C++. –

+0

Je vous suggère de télécharger un fichier simple, puis un simple fichier en utilisant base64, puis un fichier compressé en utilisant base64. J'ai eu des problèmes d'encodage et de décodage base64 dans le passé. C'est juste pour être sûr que l'interconversion base64 se passe correctement des deux côtés. –

+0

Comment puis-je envoyer un tableau d'octets dans une requête HTTP sans l'encoder avec base64? –

Répondre

0

Je n'ai pas expérimenté sur votre côté client pour l'envoi de fichiers au serveur avec HTTP.

Côté serveur, cependant, vous pouvez consulter le Spring MVC Multipart. Et du côté client, envoyer un fichier avec Multipart est une autre façon d'atteindre votre objectif.

+0

Ok, mais je ne télécharge pas de fichier, mais seulement un morceau de byte [], c'est la raison pour laquelle je ne l'ai pas envoyé en multipart. –

+1

Le problème a été résolu, voir ma dernière mise à jour. Je vous remercie. –