【问题标题】:Android & Retrofit2 - posting image file in multipart requestAndroid & Retrofit2 - 在多部分请求中发布图像文件
【发布时间】:2017-03-05 23:50:07
【问题描述】:

我正在制作一个应用程序,我必须在其中将图像从图库发送到服务器。

这些应该是标题(根据 apiary)。

Content-Type:image/jpeg
X-Filename:photo.jpg

但是在拦截器的日志中,只有 X-Filename,即使我尝试了多种方法并且我的想法已经用完了。

服务器以 200 响应,但下一次调用(提交图像)在帖子结束时返回 500 并出错。

这些是方法:

    @Multipart
    @POST("uploads")
    Observable<String> uploadImage(
        @Header("Content-Type") String contentType,
        @Header("X-Filename") String fileName,
        @Header("Authorization") String token,
        @Part MultipartBody.Part file
    );

    @GET("uploads/{fileId}/commit")
    Observable<String> commitFile(
        @Header("Content-Type") String type,
        @Header("Authorization") String token,
        @Path("fileId") String fileId
    );

OkHttp 客户端:

  private OkHttpClient createApiClient(Context context) {
      int cacheSize = 10 * 1024 * 1024; // 10 MiB
      Cache cache = new Cache(context.getCacheDir(), cacheSize);

      OkHttpClient.Builder builder = new OkHttpClient.Builder();
      builder.addInterceptor(chain -> {
          Request request = chain.request().newBuilder().build();
          request.newBuilder().addHeader("Content-Type", "application/json");
          Timber.d("Request: [%s] %s", request.method(), request.url());
          Timber.d("Request: %s", request.headers().toString());
          if (request.body() != null) {
              Timber.d("Request: %s", request.body().toString());
          }
          return chain.proceed(request);
      });
      builder.cache(cache);
      return builder.build();
  }

结果日志:

D/NetModule: Request: [POST] https://winged-guild-133523.appspot.com/api/v1/uploads
D/NetModule: Request: X-Filename: asura.png
                      Authorization: HAYVi3clcqjug53IPS6AYMgzCPGnDE3Si
D/NetModule: Request: retrofit2.RequestBuilder$ContentTypeOverridingRequestBody@7c37f46

邮递员也会发生同样的事情 - Postman screenshot

提交失败并出现此错误:(抱歉,格式丑陋)

    {
        "errorCode": "ImagesServiceFailureException",
        "errorParam": "",
        "errorMessage":"com.google.appengine.api.images.ImagesServiceFailureException: "
}

正如我所说,我的想法已经不多了,非常感谢有关此上传问题的任何帮助。

(编辑)PS: 通过在应用程序中省略 @Header("Content-Type") String contentType 并使用 application/x-www-form- Postman中的urlencoded,图片上传和提交都是成功的,但是返回url的图片没有元数据,因此无法显示。

【问题讨论】:

    标签: android image-uploading retrofit2


    【解决方案1】:

    不要使用@Multipart。相反,使用这样的东西:

     @POST("upload/image")   
     Observable<ResponseBody> uploadImage(@Body RequestBody body);
    
     File imageFile = new File(path);   
     RequestBody body =  RequestBody.create(MediaType.parse("image/jpeg"),imageFile);
    
     api.uploadImage(body);
    

    【讨论】:

    • 谢谢。对我来说不同的是能够通过将 "image/*" 更改为 "image/jpeg" 来指定文件类型。
    【解决方案2】:

    这是我使用改造的代码

    @Multipart
        @POST(ServiceConfig.API_CREATE_DEPENDENT_ACCOUNT)
        @Headers({
                "Accept: application/json",
                "Accept-Encoding: gzip"
        })
        Call<DataResponse<CreateDependentAccountResponse>>  createDependentAccount(@Query(JioConstants.ParamQuery.TOKEN) String token,
                                                                                  @Query(JioConstants.ParamQuery.USER_ID) long userID,
                                                                                  @Query(JioConstants.ParamQuery.FIRST_NAME) String firstName,
                                                                                  @Query(JioConstants.ParamQuery.LAST_NAME) String lastName,
                                                                                  @Query(JioConstants.ParamQuery.GENDER) String gender,
                                                                                  @Query(JioConstants.ParamQuery.DOB) String dob,
                                                                                  @Query(JioConstants.ParamQuery.RELATIONSHIP_ID) long relationshipID,
                                                                                  @Query(JioConstants.ParamQuery.DISPLAY_UNIT) String displayUnit,
                                                                                  @Part("avatar\"; filename=\"picture.jpg\" ") RequestBody file);
    

    RequestBody file = null;
            if (mFileTemp != null) {
                file = RequestBody.create(MediaType.parse("image/*"), mFileTemp);
            } else {
                file = RequestBody.create(MediaType.parse("image/*"), "");
            }
    
            manageCall(ServiceManager.INSTANCE2().
                    createDependentAccount(token, userID, firstName, lastName, gender, dob, relationshipID, displayUnit, file))
                    .enqueue(new SimplifiedCallback<CreateDependentAccountResponse>() {
    
                        @Override
                        public void success(CreateDependentAccountResponse data, String message) {
                            hideLoading();
    

    祝你好运。 This is my game

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2018-09-16
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 2020-12-23
      相关资源
      最近更新 更多