2013-12-10 2 views
14

내 프로젝트에서는 안드로이드 장치에서 가져온 이미지를 서버 사이트에 보내야합니다.이 이미지는 디스크에 저장해야합니다. 나는 장치 사이트의 메서드를 호출 할 때 불행하게도,이 오류 사항 :개조를 사용하여 서버에 파일 업로드

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

메소드의 선언입니다

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 

을 ... 그리고 그게 내가 그것을 호출 방법

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

서버 사이트에서 나는 그런 방법을 가지고있다 :

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

프로그램이 실패 블록에 도착하고 이유를 모르겠습니다. 누구든지 실수를 지적하고 무엇이 잘못되었는지 설명 할 수 있습니까?

는 편집

난 다음에 내가 해결할 수없는 오류가있어 내 코드에서 보정 후

:

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) 

을하고 HTTP 응답

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 

내가 생각하는 서버의 방법이 잘못 작성 될 수 있지만 확실하지 않습니다. 아무도 그것으로 도울 수 있습니까?

+0

해결 되었습니까? – dannyroa

답변

9

Uri#getPath은 파일 시스템의 경로가 아닌 Uri의 경로 구성 요소를 반환합니다.

실제 이미지에 대한 콘텐츠 공급자를 쿼리해야합니다. 다음과 같은 것 : https://stackoverflow.com/a/20186918/132047

+0

수정 한 후에 다른 오류가 발생합니다. 위의 게시물을 편집하여 서버의 사이트에 새로 추가 된 stackTrace 및 엔드 포인트 메소드를 포함 시켰습니다. 내가 뭘 잘못하고 있니? –

+0

더 많은 예외 (즉, 원인 부분)를 포함해야합니다. libcore가 깊기 때문에 수정할 수 없을 수도 있습니다. 더 나은 HTTP 클라이언트를 위해 OkHttp jar/dependency를 앱에 놓습니다. –

+0

jar가 추가되었으며 새로운 stackTrace가 위에 포함되었습니다. 제발, 아무도 그 코드가 작동하지 않는 이유를 설명 할 수 있습니까? 그것은 retrofit 같이 헤더의 콘텐츠 길이 부분을 설정할 수없는 것 같습니다 –