提问者:小点点

无法在 OkHttp 中为 MultipartBody.Part 设置 Content-Type


在为这个问题挣扎了几个小时之后,我终于决定在这里寻求建议。我在应用程序中使用 Retrofit 2 进行联网。这是我在 API 接口中上传图像的方法的样子:

@POST(UPLOAD_PHOTO)
@Multipart
Call<UploadPhotoResponse> uploadPhoto(@Header("X-Auth-Token") String token, @Path("post_id") int postId
        , @Part("photo\"; filename=\"cover.jpg\"") MultipartBody.Part photo, @Part("photo_thumb\"; filename=\"cover_thumb.jpg\" ") MultipartBody.Part photoThumb);

广告是这样称呼它的:

    RequestBody photoBody = RequestBody.create(MediaType.parse("image/jpeg"),bytePhoto);
    RequestBody thumbBody = RequestBody.create(MediaType.parse("image/jpeg"), byteThumb);
    MultipartBody.Part photoPart = MultipartBody.Part.createFormData("photo", photoFile.getName(), photoBody);
    MultipartBody.Part thumbPart = MultipartBody.Part.createFormData("photo_thumb", thumbFile.getName(), thumbBody);
    Call<UploadPhotoResponse> call = apiService
            .uploadPhoto(sessionToken, postId, photoPart, thumbPart);
    call.enqueue(new Callback<UploadPhotoResponse>() {
        @Override
        public void onResponse(Response<UploadPhotoResponse> response, Retrofit retrofit) {

        }

        @Override
        public void onFailure(Throwable t) {

        }
    });

我的问题是由于不正确的正文参数,我从服务器收到错误消息。对于某些 reson 每个部分的内容类型都设置为“application/json”,如 Fiddler 的屏幕所示: 请求正文参数

我发现的唯一与我的问题相关的讨论是多部分请求覆盖内容类型不起作用#1433

但它是关于请求标头的内容类型,而不是正文部分的内容类型。也许有人在 OkHttp 上遇到了类似的问题,因为现在我无法解决任何问题,除了从这个库切换到这个特定请求。


共1个答案

匿名用户

我目前遇到同样的问题,因为我正在尝试发送字符串和图片,两者都应该是多部分/表单数据。

界面如下所示:

@Multipart
    @POST("photos/setPhotos")
    Observable<SetPhotoResponseWrapper> uploadPhoto(@Part("userHash") RequestBody userHash, @Part("photos[]") MultipartBody.Part file);

以及如何创建对象:

RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);

        MultipartBody.Part multipart = MultipartBody.Part.createFormData("picture", file.getName(), reqFile);

        RequestBody userBody = RequestBody.create(MediaType.parse("multipart/form-data"), userHash);

以下是来自okHttp的日志:

Content-Disposition: form-data; name="userHash"
10-12 14:23:43.951 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Transfer-Encoding: binary
10-12 14:23:43.951 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Type: multipart/form-data; charset=utf-8
10-12 14:23:43.951 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Length: 32
10-12 14:23:43.952 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Disposition: form-data; name="photos[]"
10-12 14:23:43.952 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Transfer-Encoding: binary
10-12 14:23:43.952 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Type: application/json; charset=UTF-8
10-12 14:23:43.952 29991-30723/com.gigrev.gigkev D/OkHttp: Content-Length: 111
10-12 14:23:43.952 29991-30723/com.gigrev.gigkev D/OkHttp: {"headers":{"namesAndValues":["Content-Disposition","form-data; name=\"picture\"; filename=\"IMAG0203.jpg\""]}}

由于后端不接受 json,我必须自己弄清楚。你设法找到解决方案了吗?

编辑:我实际上找到了一个解决方案。刚刚更新了改造版本,这就是我现在在日志中得到的内容:

 Content-Disposition: form-data; name="userHash"
10-12 14:55:59.775 24479-25505/com.gigrev.gigkev D/OkHttp: Content-Transfer-Encoding: binary
10-12 14:55:59.775 24479-25505/com.gigrev.gigkev D/OkHttp: Content-Type: multipart/form-data; charset=utf-8
10-12 14:55:59.775 24479-25505/com.gigrev.gigkev D/OkHttp: Content-Length: 32
10-12 14:55:59.775 24479-25505/com.gigrev.gigkev D/OkHttp: Content-Disposition: form-data; name="picture"; filename="IMAG0204.jpg"
10-12 14:55:59.775 24479-25505/com.gigrev.gigkev D/OkHttp: Content-Type: multipart/form-data
10-12 14:55:59.775 24479-25505/com.gigrev.gigkev D/OkHttp: Content-Length: 848314

改造版本:

compile 'com.squareup.retrofit2:retrofit:2.0.1'
    compile 'com.squareup.retrofit2:converter-gson:2.0.1'