2013-12-10 14 views
14

In meinem Projekt muss ich ein Bild von Android-Gerät an die Server-Website gesendet, wo es auf der Festplatte gespeichert werden soll. Leider treffe ich diesen Fehler, wenn ich die Methode auf dem Gerät Website aufrufen:Hochladen von Datei auf dem Server mithilfe von Retrofit

DEBUG/Retrofit(4429): java.lang.RuntimeException: 
    Unable to write multipart request. 
at retrofit.mime.MultipartTypedOutput.buildPart(MultipartTypedOutput.java:86) 
at retrofit.mime.MultipartTypedOutput.addPart(MultipartTypedOutput.java:49) 
at retrofit.RequestBuilder.setArguments(RequestBuilder.java:211) 
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:264) 
at retrofit.RestAdapter$RestHandler.access$500(RestAdapter.java:197) 
at retrofit.RestAdapter$RestHandler$1.obtainResponse(RestAdapter.java:243) 
at retrofit.CallbackRunnable.run(CallbackRunnable.java:38) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
at retrofit.Platform$Android$2$1.run(Platform.java:134) 
at java.lang.Thread.run(Thread.java:856) 

Caused by: java.io.FileNotFoundException: /external/images/media/1270: 
    open failed: ENOENT (No such file or directory) 
at libcore.io.IoBridge.open(IoBridge.java:416) 
at java.io.FileInputStream.<init>(FileInputStream.java:78) 
at retrofit.mime.TypedFile.writeTo(TypedFile.java:74) 
at retrofit.mime.MultipartTypedOutput.buildPart(MultipartTypedOutput.java:83) 
... 10 more 

Caused by: libcore.io.ErrnoException: 
    open failed: ENOENT (No such file or directory) 
at libcore.io.Posix.open(Native Method) 
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 
at libcore.io.IoBridge.open(IoBridge.java:400) 
... 13 more 

, dass die Erklärung der Methode ist

@Multipart 
@POST("/monument/photo/upload") 
void addMonumentPhoto(@Part("MonumentID") int monumentId, 
         @Part("name") String name, 
         @Part("subscript") String subscript, 
         @Part("photo") TypedFile photo, 
         Callback<Photo> callback); 

... und das ist, wie ich es nennen

photo = new File(selectedImageUri.getPath()); 
typedFile = new TypedFile("application/octet-stream", photo); 
MonumentsUtil.getApi().addMonumentPhoto(monument.getIdZabytek(), 
     "podpis", 
     "Main photo", 
     typedFile, 
     new Callback<Photo>() { 
    @Override 
    public void success(Photo aPhoto, Response response) { 
    } 

    @Override 
    public void failure(RetrofitError retrofitError) { 
     Log.e(TAG, retrofitError.getMessage()); 
    } 
}); 

Auf der Website des Servers habe ich solche Methoden:

@RequestMapping(value="/monument/photo/upload", method=RequestMethod.POST) 
public @ResponseBody Photo requestMonumentPhotoAdd(
     @RequestParam("MonumentID") int monumentId, 
     @RequestParam("name") String name , 
     @RequestParam("subscript") String subscript, 
     @RequestParam("photo") org.springframework.web.multipart.MultipartFile file) { 

    Photo photo = new Photo(); 
    photo.setIdZabytek(monumentId); 
    photo.setUri(URL+ "/images/" + name); 
    photo.setPodpis(subscript); 
    photo = monumentsRepo.addPhoto(photo); 
    String filePath = "D:\\Projekty\\Images\\" + monumentId + ":" + photo.getIdZjecia(); 

    if (!file.isEmpty()) { 
     try { 
      byte[] bytes = file.getBytes(); 
      BufferedOutputStream stream = new BufferedOutputStream(
       new FileOutputStream(new File(filePath))); 
      stream.write(bytes); 
      stream.close(); 
      photo.setUri(filePath); 
      monumentsRepo.updatePhoto(photo); 
      return photo; 
     } catch (Exception e) { 
      return null; 
     } 
    } else { 
     return null; 
    } 
} 

Das Programm kommt zum Fehlerblock und ich weiß nicht warum. Kann jemand den Fehler aufzeigen und erklären, was falsch ist?

EDIT

Nach der Korrektur in meinem Code ich nächsten Fehler habe, die ich nicht beheben kann:

java.net.ProtocolException: content-length promised 1431984 bytes, but received 0  
    com.squareup.okhttp.internal.http.RetryableOutputStream.close(RetryableOutputStream.java:52), 
    com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:629), 
    com.squareup.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java: 346), 
    com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:295), 
    com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:489), 
retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:90), 
retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:48), 
retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:287), 
retrofit.RestAdapter$RestHandler.access$500(RestAdapter.java:197), 
retrofit.RestAdapter$RestHandler$1.obtainResponse(RestAdapter.java:243), 
retrofit.CallbackRunnable.run(CallbackRunnable.java:38), 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076), 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569), 
retrofit.Platform$Android$2$1.run(Platform.java:134), 
java.lang.Thread.run(Thread.java:856) 

und die HTTP-Response-

HTTP/1.1 400 Bad Request, 
Connection: close, 
Content-Length: 1068, 
Content-Type:  text/html;charset=utf-8, 
Date: Wed, 11 Dec 2013 16:45:39 GMT, 
OkHttp-Received-Millis: 1386780339873, 
OkHttp-Response-Source: NETWORK 400, 
OkHttp-Selected-Transport: http/1.1, 
OkHttp-Sent-Millis: 1386780339799, Server: Apache-Coyote/1.1 

Ich denke, dass der Server des Methode könnte falsch geschrieben werden, aber ich bin mir nicht sicher. Könnte jemand damit helfen?

+0

Wurde das gelöst? – dannyroa

Antwort

9

Uri#getPath gibt die Pfadkomponente des Uri, nicht den Pfad auf dem Dateisystem zurück.

Sie müssen den Inhaltsanbieter nach dem tatsächlichen Bild fragen. Etwas wie dieses: https://stackoverflow.com/a/20186918/132047

+0

Nach der Korrektur treffe ich einen anderen Fehler. Ich habe den obigen Post bearbeitet, um den neuen StackTrace von Retrofit und die Endpunkt-Methode auf der Server-Seite zu integrieren. Was mache ich falsch? –

+0

Sie müssen mehr von der Ausnahme einschließen (d. H. Den Cause-Teil). Das ist tief in libcore, so dass Sie es möglicherweise nicht beheben können. Löschen Sie die OkHttp-JAR/Abhängigkeit für einen besseren HTTP-Client in Ihrer App. –

+0

Das Glas wurde hinzugefügt und das neue stackTrace wurde oben eingefügt. Kann jemand erklären, warum dieser Code nicht funktioniert? Es scheint, als ob Retrofit den inhaltlichen Teil des Headers nicht einstellen konnte –