Android Retrofit使用多部分请求上传图像文件

4

我对Android Retrofit不熟悉,需要使用多部分请求格式上传图像文件。我已经成功地使用iPhone多部分请求上传了文件。但是,在使用Android Retrofit时遇到了问题。我正在使用HTTPS和令牌承载授权。

@Multipart
@POST("/Api/ApiSales/UploadImages")
void uploadImage(@Part("File") TypedFile file,
                      Callback<Response> callback);

RestAdapter.Builder builder = new RestAdapter.Builder().setEndpoint(appController.getInstance().getURL());
            builder.setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade request) {
                    request.addHeader("Authorization", appController.getInstance().getAuthTokenString());
                }
            });
            builder.setLogLevel(RestAdapter.LogLevel.FULL);

            RestAdapter restAdapter = builder.build();

            RetrofitService service = restAdapter.create(RetrofitService.class);
            service.uploadImage(new TypedFile("image/png",toFile), new Callback<retrofit.client.Response>() {
                @Override
                public void success(retrofit.client.Response response, retrofit.client.Response response2) {
                    Log.i(TAG, response.toString());
                }

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

我得到了以下错误:

retrofit.RetrofitError: Write error: ssl=0x5ef8ad40: I/O error during system call, Connection reset by peer      

我为HTTP请求设置了服务器,但仍然出现错误:

  retrofit.RetrofitError: sendto failed: ECONNRESET (Connection reset by peer)

SSL连接出现问题。请参考此处类似的SSL错误 https://code.google.com/p/android/issues/detail?id=65463 - Nikola Despotoski
我尝试了其他的GET/POST JSON请求,都能正常工作,除了上传文件请求之外,所以可能是其他地方出了问题。我去掉了SSL并使用普通的HTTP请求,但仍然出现错误。 - Tony Lin
嘿,你找到解决方法了吗?我也遇到了同样的问题。谢谢提前帮忙! - Abhinav
似乎我的服务器路由器出了问题,这段代码在另一台服务器上可以运行。 - Tony Lin
1个回答

0

我认为你的界面应该是这样的。

 @Multipart
    @POST("/Api/ApiSales/UploadImages") 
    void uploadImage(@Header("Authorization") String user, 
    @Part("File") TypedFile file, Callback<Response> callback);

你应该先从onActivityResult中获取真实的图像路径

final String imagePath = getRealPathFromURI(imageUri);

而 getRealPathFromURI 将会是这样。

private String getRealPathFromURI(Uri contentUri) {
        String[] projection = {MediaStore.Images.Media.DATA};
        CursorLoader loader = new CursorLoader(this, contentUri, projection, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String result = cursor.getString(column_index);
        cursor.close();
        return result;
    }

以及您的TypedFile的初始化

File photoFile = new File(imagePath);// image will be your real path
        String mimeType = getMimeType(imagePath);
        TypedFile photoTypedFile;
        if (mimeType != null) {
            photoTypedFile = new TypedFile(mimeType, photoFile);
        } else {
            photoTypedFile = new TypedFile("image/jpg", photoFile);
        }

你的Restadapter初始化将保持不变,只需添加头信息即可,然后你的调用将会是这样。

RetrofitService service = restAdapter.create(RetrofitService.class);
            service.uploadImage("yourAuthorization", photoTypedFil, new Callback<retrofit.client.Response>() {
                @Override
                public void success(retrofit.client.Response response, retrofit.client.Response response2) {
                    Log.i(TAG, response.toString());
                }

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接