1. ホーム
  2. android

[解決済み] Retrofit 2.0を使用したPOSTマルチパートフォームデータ(画像付き

2022-04-20 15:32:05

質問

を使用してサーバーに HTTP POST しようとしています。 レトロフィット2.0

MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain");
MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    imageBitmap.compress(Bitmap.CompressFormat.JPEG,90,byteArrayOutputStream);
profilePictureByte = byteArrayOutputStream.toByteArray();

Call<APIResults> call = ServiceAPI.updateProfile(
        RequestBody.create(MEDIA_TYPE_TEXT, emailString),
        RequestBody.create(MEDIA_TYPE_IMAGE, profilePictureByte));

call.enqueue();

サーバーは、ファイルが無効であるというエラーを返します。

iOSで同じファイルを同じフォーマットでアップロードしようとしましたが(他のライブラリを使用)、正常にアップロードされたので、これは奇妙なことです。

を使用して画像をアップロードする適切な方法は何でしょうか? レトロフィット2.0 ?

アップロードする前に、まずディスクに保存したほうがいいのでしょうか?

追伸:画像を含まない他のMultipartリクエストにretrofitを使用したことがあり、それらは正常に完了しました。問題は、ボディにバイトを含めようとしたときです。

解決方法は?

1.9と2.0の両方で解決策をハイライトしています。

1.9 というように、ファイルをディスクに保存して、それをTypedファイルとして使用するのが良い解決策だと思います。

RetroFit 1.9

(サーバー側の実装は知りませんが)APIインターフェースに以下のようなメソッドを用意してください。

@POST("/en/Api/Results/UploadFile")
void UploadFile(@Part("file") TypedFile file,
                @Part("folder") String folder,
                Callback<Response> callback);

そして、次のように使用します。

TypedFile file = new TypedFile("multipart/form-data",
                                       new File(path));

RetroFit 2 の場合 次の方法で使用します。

RetroFit 2.0 ( の回避策でした。 問題 は、RetroFit 2 で修正され、正しいメソッドは jimmy0251の回答 )

APIインターフェイスです。

public interface ApiInterface {

    @Multipart
    @POST("/api/Accounts/editaccount")
    Call<User> editUser(@Header("Authorization") String authorization,
                        @Part("file\"; filename=\"pp.png\" ") RequestBody file,
                        @Part("FirstName") RequestBody fname,
                        @Part("Id") RequestBody id);
}

のように使います。

File file = new File(imageUri.getPath());

RequestBody fbody = RequestBody.create(MediaType.parse("image/*"),
                                       file);

RequestBody name = RequestBody.create(MediaType.parse("text/plain"),
                                      firstNameField.getText()
                                                    .toString());

RequestBody id = RequestBody.create(MediaType.parse("text/plain"),
                                    AZUtils.getUserId(this));

Call<User> call = client.editUser(AZUtils.getToken(this),
                                  fbody,
                                  name,
                                  id);

call.enqueue(new Callback<User>() {

    @Override
    public void onResponse(retrofit.Response<User> response,
                           Retrofit retrofit) {

        AZUtils.printObject(response.body());
    }

    @Override
    public void onFailure(Throwable t) {

        t.printStackTrace();
    }
});