Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Upload a File using Retrofit 2.0 #1063

Closed
vivekkiran opened this issue Sep 7, 2015 · 100 comments
Closed

How to Upload a File using Retrofit 2.0 #1063

vivekkiran opened this issue Sep 7, 2015 · 100 comments

Comments

@vivekkiran
Copy link

How to upload a file using multipart/form-data upload in Retrofit 2.0, I am unable to upload and there is no proper documentation anywhere on uploading file using retrofit 2.0, I followed the docs in retrofit website but I was not able to make it work.

All the examples I see used TypedFile. It is not clear how to use RequestBody. Please post sample code.

@JakeWharton
Copy link
Member

Same as v1. Use the Multipart annotation on the method and Part annotation
on parameters.

On Mon, Sep 7, 2015, 7:06 AM Vivek Kiran notifications@github.com wrote:

How to upload a file using multipart upload in Retrofit 2.0


Reply to this email directly or view it on GitHub
#1063.

@JakeWharton
Copy link
Member

Oh for the file itself, use RequestBody for the type.

On Mon, Sep 7, 2015, 10:50 AM Jake Wharton jakewharton@gmail.com wrote:

Same as v1. Use the Multipart annotation on the method and Part annotation
on parameters.

On Mon, Sep 7, 2015, 7:06 AM Vivek Kiran notifications@github.com wrote:

How to upload a file using multipart upload in Retrofit 2.0


Reply to this email directly or view it on GitHub
#1063.

@VadimWelldone
Copy link

Hi,

I am getting following exception while executing:

@Headers("User-Agent: " + Constants.CLIENT_NAME)
@Multipart
@POST(Constants.Urls.SYNC_URL)
Call<BaseResponseDto> uploadFile(@Part("file") RequestBody song, @Part("file_path") String fileName, @Part("method") String method, @Part("user_id") String userId, @Part("token") String token);

09-07 17:49:38.072 13562-13582/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented

java.lang.IllegalStateException: JSON must start with an array or an object.
at com.google.gson.stream.JsonWriter.beforeValue(JsonWriter.java:609)
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:418)
at com.google.gson.internal.bind.TypeAdapters$13.write(TypeAdapters.java:362)
at com.google.gson.internal.bind.TypeAdapters$13.write(TypeAdapters.java:346)
at com.google.gson.TypeAdapter.toJson(TypeAdapter.java:142)
at retrofit.GsonConverter.toBody(GsonConverter.java:55)
at retrofit.RequestBuilderAction$Part.perform(RequestBuilderAction.java:204)
at retrofit.RequestFactory.create(RequestFactory.java:62)
at retrofit.OkHttpCall.createRawCall(OkHttpCall.java:116)
at retrofit.OkHttpCall.execute(OkHttpCall.java:106)
at retrofit.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:59)
at com.ibroadcast.mediasynclite.api.upload.UploadRunnable.run(UploadRunnable.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

Everything worked until I migrated to Retrofit 2.0. Is anything wrong with my request?

Thanks in advance.

@JakeWharton
Copy link
Member

Retrofit 2 is not released so I'll assume you mean the beta1. This is
already fixed in master and will be in the next release.

On Mon, Sep 7, 2015, 6:06 PM Vadim Oleynik notifications@github.com wrote:

Hi,

I am getting following exception while executing:

@headers("User-Agent: " + Constants.CLIENT_NAME)
@multipart
@post(Constants.Urls.SYNC_URL)
Call uploadFile(@part("file") RequestBody song, @part("file_path") String fileName, @part("method") String method, @part("user_id") String userId, @part("token") String token);

09-07 17:49:38.072 13562-13582/? W/EGL_emulation﹕ eglSurfaceAttrib not
implemented

java.lang.IllegalStateException: JSON must start with an array or an
object.
at com.google.gson.stream.JsonWriter.beforeValue(JsonWriter.java:609)
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:418)
at
com.google.gson.internal.bind.TypeAdapters$13.write(TypeAdapters.java:362)
at
com.google.gson.internal.bind.TypeAdapters$13.write(TypeAdapters.java:346)
at com.google.gson.TypeAdapter.toJson(TypeAdapter.java:142)
at retrofit.GsonConverter.toBody(GsonConverter.java:55)
at
retrofit.RequestBuilderAction$Part.perform(RequestBuilderAction.java:204)
at retrofit.RequestFactory.create(RequestFactory.java:62)
at retrofit.OkHttpCall.createRawCall(OkHttpCall.java:116)
at retrofit.OkHttpCall.execute(OkHttpCall.java:106)
at
retrofit.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:59)
at
com.ibroadcast.mediasynclite.api.upload.UploadRunnable.run(UploadRunnable.java:49)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

Everything worked until I migrated to Retrofit 2.0. Is anything wrong with
my request?

Thanks in advance.


Reply to this email directly or view it on GitHub
#1063 (comment).

@JakeWharton
Copy link
Member

Use the latest snapshot for the fix, or wait until the next release.

@VadimWelldone
Copy link

Actually, I have downloaded the latest version using:

  1. maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
  2. compile 'com.squareup.retrofit:retrofit:2.0.0-SNAPSHOT'
  3. gradle clean
  4. rebuild project

But issue still exists :(

On Mon, Sep 7, 2015 at 7:25 PM, Jake Wharton notifications@github.com
wrote:

Closed #1063 #1063.


Reply to this email directly or view it on GitHub
#1063 (comment).

@CBGallarno
Copy link

I have also tried the same as VadimWelldone, and experienced no change or fix of the problem.

Edit: After some messing around this seems to be a problem with multi parts and not the use of RequestBody's

@VadimWelldone
Copy link

Thanks Ashig. I'll try it a little bit later. Hope your approach will
resolve existing issue.

On Mon, Sep 14, 2015, 7:30 AM Ashiq Uz Zoha notifications@github.com
wrote:

I have a tested solution about this issue. You'll need to send to all
parameters as RequestBody.

@multipart
@post("/api/Accounts/addaccount")
Call signup(
@part("FirstName") RequestBody fname,
@part("LastName") RequestBody lname,
@part("email") RequestBody email,
@part("password") RequestBody password,
@part("username") RequestBody uname,
@part("Newsletter") RequestBody nl
);

And we need to call the method like this...

Call call = client.signup(
RequestBody.create(MediaType.parse("text"),firstNameField.getText().toString().getBytes()),
RequestBody.create(MediaType.parse("text"), lastNameField.getText().toString().getBytes()),
RequestBody.create(MediaType.parse("text"), emailField.getText().toString().getBytes()),
RequestBody.create(MediaType.parse("text"), passwordField.getText().toString().getBytes()),
RequestBody.create(MediaType.parse("text"), userNameField.getText().toString().getBytes()),
RequestBody.create(MediaType.parse("text"), toByteArray(bits))
);

Hope it helps.


Reply to this email directly or view it on GitHub
#1063 (comment).

@ayon115
Copy link

ayon115 commented Sep 15, 2015

Hello @VadimWelldone , I deleted that comment because after spending some more time, I noticed that for doing that approach I get status code 200 as response (may be because of my backend) but those parameters don't actually gets stored to my database correctly. So, thats not actually a solution.

But here is my real finding why. I am almost sure that, the Multipart request (file upload) is from okhttp. Retrofit probably has nothing to do with it. My Multipart request has both text and image data. When I pack all my text data into a PartMap and use @PartMap in Retrofit, these things gets Posted to backend correctly.

But there's problem with image or file upload. Retrofit 2.0 tells to use okhttp RequestBody to send file. I tried that both with Retrofit and Standalone okhttp library. None of my attempt could successfully upload the file to backend. So, I guess, this problem is from okhttp and we know Retrofit 2.0 uses it as default client. And I confirm that my API is fine as I can POST image and texts in single Multipart request with Android Volley.

@jimxj
Copy link

jimxj commented Sep 15, 2015

I had problem to upload file using Retrofit 2.0-SNAPSHOT before and found out the multipart format is not compatible with my server which accepts multipart/form-data. Here is my fix : jimxj@b44ab36

@wKovacs64
Copy link

Still getting java.lang.IllegalStateException: JSON must start with an array or an object. from Gson when trying to post a multipart request where one of the parts is a file.

Retrofit 1.9.0 (using OkHttp 2.5.0):

    @Multipart
    @POST("/image/upload")
    Observable<UploadImageResponse>
    uploadImage(@Header(HEADER_AUTH_KEY) String token,
                @Part("userId") String userId,
                @Part("images") TypedFile file);

Where the file parameter is constructed as follows:

TypedFile file = new TypedFile("image/*", new File(path));

Retrofit 2.0.0-SNAPSHOT:

    @Multipart
    @POST("image/upload")
    Observable<UploadImageResponse>
    uploadImage(@Header(HEADER_AUTH_KEY) String token,
                @Part("userId") String userId,
                @Part("images") RequestBody file);

Where the file parameter is constructed as follows:

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

Am I doing something incorrectly, or is this not the same thing that @JakeWharton said was fixed in master? Did you get it to work, @VadimWelldone?

I did notice Gson can serialize TypedFile to JSON, but trying the same thing on RequestBody returns null. Related? I might be barking up the wrong tree here.

@tevjef
Copy link

tevjef commented Sep 25, 2015

A fixed was recently merged #1092 (comment). Is it already in the snapshot?

@JakeWharton
Copy link
Member

snapshots are automatically deployed

On Thu, Sep 24, 2015 at 10:27 PM Tevin Jeffrey notifications@github.com
wrote:

A fixed was recently merged #1092 (comment)
#1092 (comment). Is it
already in the snapshot?


Reply to this email directly or view it on GitHub
#1063 (comment).

@VadimWelldone
Copy link

@wKovacs64 It's very sad but I didn't manage to get it to work. I have rolled back to Retrofit 1.9.0 and continued to use it. Time frames was crucial for me and I chose working solution.

@waleoyediran
Copy link

Possibly related @VadimWelldone issue
I'm using 2.0.0-beta2.
and using the converter GsonConverterFactory

It seem it was serializing the file as a Form Field instead of a File Field

Debugging from a Python(Flask) server showed that

print request.form
print request.files

ImmutableMultiDict([('file-field', u'/PATH/TO/FILE/FILE-NAME.jpg'), ('field', u'"value"')])
ImmutableMultiDict([])

rather than

ImmutableMultiDict([('field', value')])
ImmutableMultiDict([('file-field', <FileStorage: u'FILE-NAME.jpg' ('image/jpeg')>)])

@wKovacs64
Copy link

2.0.0-beta2 got me past the JSON problem (not sure why the snapshot didn't help). Now investigating the lack of filename key in the Content-Disposition header field, as mentioned in #1096 (comment) and the second half of #1130.

Do you have the headers from that request, @waleoyediran? I'm assuming yours must've included the filename somehow if you're seeing it on the web server like that.

@ayon115
Copy link

ayon115 commented Sep 30, 2015

I just tested with the method commented in #1140 and confirm that it works correctly. I am able to upload file in Multipart Request successfully. Sample code is below

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" within @part annotation is the name of the file parameter and "filename" is the name of the file that's going to be uploaded.

I executed the above request like this...

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

Hope it helps.

@sungjin0213
Copy link

@ayon115 Thank you so much. It really helped.

@mengoni
Copy link

mengoni commented Oct 6, 2015

@ayon115 Thanks, it works! But how to specify a dynamic filename in the interface (or in the RequestBody)?

@ayon115
Copy link

ayon115 commented Oct 6, 2015

@mengoni , I think we can't specify dynamic filename in the interface right now. As far I know, it's probably okhttp matter. I am using @PartMap to avoid hard-coding filename with Interface method. You can see the following example that might be useful.

 @Multipart
 @POST ("/api/Events/editevent")
 Call<Event> editEvent (@PartMap Map<String, RequestBody> params);

I call it by following way.

Map<String, RequestBody> map = new HashMap<>();
map.put("Id", AZUtils.toRequestBody(eventId));
map.put("Name", AZUtils.toRequestBody(titleView.getValue()));

if (imageUri != null) {
      File file = new File(imageUri.getPath());
      RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
      map.put("file\"; filename=\"pp.png\"", fileBody);
}

Call<Event> call = api.editEvent(map);
call.enqueue(new Callback<Event>() { }

The method toRequestBody just converts String into RequestBody

 public static RequestBody toRequestBody (String value) {
        RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value);
        return body ;
    }

@mhousser
Copy link

@ayon115 saved me as well. After upgrading from 1.9, in which I effortlessly uploaded image files with a @Multipart endpoint and a TypedFile attribute, the only thing I could do in Retrofit 2.0 was this ugly guy:

@Part("image\"; filename=\"image.jpg\" ") RequestBody image,

It works. This, unfortunately, does not work, as the back end can not find a FILE param named 'image':

@Part("image") RequestBody image,

@wKovacs64
Copy link

@mhousser The way forward is being discussed/tracked in #1140. I have a PR in to essentially bring back a version of the old TypedFile API, if that interests you. The end result would look something like this:

File file = /* ... */;
TypedFile image = new TypedFile("image/png", file);

// ...

@PartFile("image") TypedFile image

...which should look familiar.

@mhousser
Copy link

Thanks!

@Part("image\"; filename=\"image.jpg\" ") RequestBody image

Is pretty hideous, but it works for now. I can hard-code the filename because I don't actually pay attention to it or use it server-side. (I hope this doesn't cause conflicts between different users uploading with the same filename..?)

@abcdeiko
Copy link

Is anybody know how i can show progress when i'm uploading a file?

@lectricas
Copy link

lectricas commented Apr 21, 2016

Yes, @kafji, I've seen this guide. It is for OKHTTP , not for retrofit. I've already implemented my request using okhttp only but it's not enough. I need to make it with retfit. Nice EXAMPLE android project with all the features implemented would be more that enought for all who struggles.

@markini
Copy link

markini commented Apr 21, 2016

My solution for this problem:

@Multipart
@POST("/api/.../{id}/audio")
Call<MyResponse> sendAudio(
        @Path("id") String id,
        @Part MultipartBody.Part part
);

Called like this:

RequestBody requestBody = RequestBody.create(MEDIA_TYPE_AUDIO, audioFile);
MultipartBody.Part part = MultipartBody.Part.createFormData("message_audio[audio]", audioFile.getName(), requestBody);
service.sendAudio(id, part)...

@sumit269
Copy link

What worked for me is as follows:

@Multipart
    @POST("users/{id}/avatar")
    Observable<Void> uploadAvatar(@Header("Authorization") String token, @Path("id") String userId, @Part("source\"; filename=\"image.jpg") RequestBody image);

Note that the difference from a few other answers here is filename="image.jpg" without the escape char at the end.

@lectricas
Copy link

  MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart(ParkApiUrl.PARAM_USER_NAME, name)
                .addFormDataPart(ParkApiUrl.PARAM_USER_SECOND_NAME, last)
                .addFormDataPart(ParkApiUrl.PARAM_EMAIL, email)
                .addFormDataPart(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD,
                        PasswordUtils.encodePassword(pwd))
                .addFormDataPart(ParkApiUrl.PARAM_USER_GENDER, sex)
                .addFormDataPart(ParkApiUrl.PARAM_PARSE_ID,
                        ParseInstallation.getCurrentInstallation().getObjectId());

        if (!TextUtils.isEmpty(avatarPath)) {

            Log.d("RegistrationFragment", avatarPath);
            File file = new File(avatarPath);
            int size = (int) file.length();
            byte[] bytes = new byte[size];
            try {
                BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
                buf.read(bytes, 0, bytes.length);
                buf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"photo\"; filename=\"image.jpg\""), RequestBody.create(MEDIA_TYPE_JPG, bytes));
        }

work like a charm!

@mikhail24
Copy link

@sbljayarathna
Copy link

This is my code. This works...


public interface FileUploadService {  
    @Multipart
    @POST("upload")
    Call<ResponseBody> upload(@PartMap Map<String, RequestBody> params);
}

 private void uploadFile() {  
        FileUploadService service =
                ServiceGenerator.createService(FileUploadService.class);

        File file = new File(selectedImagePath);
image_name = file.getName();
String fileName = "file\"; filename=\"" + image_name;
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);

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

Map<String, RequestBody> requestBodyMap = new HashMap<>();
 requestBodyMap.put("id", id);
requestBodyMap.put(fileName, requestBody);


        Call<ResponseBody> call = service.upload(requestBodyMap);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call,
                                   Response<ResponseBody> response) {
                Log.v("Upload", "success");
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e("Upload error:", t.getMessage());
            }
        });
    }

@thaninrat-p
Copy link

thaninrat-p commented Jul 8, 2016

This is my code and it's working flawlessly

Service

@Multipart
@POST("File/upload")
Observable<UploadImageApiResult> uploadImage(
    @Part("token") RequestBody token,
    @Part("player_id") RequestBody playerId,
    @Part MultipartBody.Part image
);

Call

restClient.getImageService().uploadImage(
    RequestBody.create(MediaType.parse("text/plain"), getApiToken()),
    RequestBody.create(MediaType.parse("text/plain"), form.getPlayerId()),
    MultipartBody.Part.createFormData(
        "file",
        form.getFile().getName(),
        RequestBody.create(MediaType.parse("image/*"), form.getFile())
    )
)

@bhargavms
Copy link

@Tar-SSA How are you able to use @Part without passing a value to it like so @Part("blah") ?? that annotation gives a compile time error if one uses it like you have

@thaninrat-p
Copy link

@bhargavms

This is my dependencies related to Retrofit

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'

Are they the same with yours?

@bhargavms
Copy link

@Tar-SSA ah thank you I was still using the 2.0.0-beta version and hence the issue

@pro100svitlo
Copy link

pro100svitlo commented Jul 18, 2016

I was never work with Jsoup before, and now I have a project, where guys were using JSoup lib, and I need to do some refactoring and make same work but with retrofit2...

I stuck with converting request that send image file. Here is original JSoup request:

Connection.Response result = Jsoup.connect(apiURL + "sendImg/")
                                    .method(Connection.Method.POST)
                                    .header("Token", XCSRFToken)
                                    .data("source", currentImage.getMD5().concat(".jpg"), 
                                           new FileInputStream(bitmapURI.getPath()))
                                    .execute();

here is what i try to do with retrofit:

```

@multipart
@post("sendImg/")
Call sendImage(@Header("Token") String token, @part MultipartBody.Part file);

public void sendImage(File file) {
        RequestBody requestFile =
                RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body =
        MultipartBody.Part.createFormData("source",
                        currentImage.getMD5().concat(".jpg"), requestFile);
        mSendImageCall = mServerApi.sendImage(getToken(), body);
        mSendImageCall.enqueue(sendImageCallback);
}
but request still failed...

Any ideas how convert that request correct? Thanks!

@pro100svitlo
Copy link

@Tar-SSA , @sbljayarathna , @lectricas , @markini , @jemshit , @CateyesLin , @DeepakRattan ??
Anyone? Please help to find solution!

@JakeWharton
Copy link
Member

This is not a help forum. Try StackOverflow.

@aman4india
Copy link

aman4india commented Sep 29, 2016

@multipart
@post("/uploadFile")
Call postFile(
@part("empsno") String empsno,
@part("storesno") String storesno,
@part("lrSno") String lrSno,
@part("recQty") String recQty,
@part("recVol") String recVol,
@part("recWgt") String recWgt,
@part("damageQty") String damageQty,
@part("looseQty") String looseQty,
@part("deliveryDate") String deliveryDate,
@part("deliveryTime") String deliveryTime,
// @part("uploadFile") RequestBody file,
// @part("uploadFile";filename="audex.jpg" ") RequestBody part,
@part("remarks") String remarks,
@part("receivedBy") String receivedBy,
@part("ipAddress") String ipAddress,
@part MultipartBody.Part images
);

          private void uploadFile(Uri fileUri) {
           File file = new File(fileUri.getPath());
          if (file.exists()) {
            Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        Log.e(TAG, "uploadFile:File " + file);
        MediaType MEDIA_TYPE_PNG = MediaType.parse("multipart/form-data");

        AudexInterface service = retrofit.create(AudexInterface.class);

        RequestBody requestFile = RequestBody.create(MEDIA_TYPE_PNG, file);

        MultipartBody.Part filePart = MultipartBody.Part.createFormData("uploadFile", file.getName(),
                RequestBody.create(MediaType.parse("image/*"), file));

        Log.e(TAG, "uploadUri: " + strEmpsno + " " + strStoreSno + "  " + strLrno + "  " + strRecqty + "  " + strDeliverydate + " " + strDeliverytime);
        Call<PODResponse> call = service.postFile(strEmpsno,
                strStoreSno,
                strLrno,
                strRecqty,
                strRecvol,
                strRecwgt,
                strDamageqty,
                strLooseqty,
                strDeliverydate,
                strDeliverytime,
                //                    requestFile,
                strRemarks,
                strReceivedby,
                strIpaddress,
                filePart);

        call.enqueue(new Callback<PODResponse>() {
            @Override
            public void onResponse(Call<PODResponse> call, Response<PODResponse> response) {
                Log.e(TAG, "onResponse:uploadUri " + response.isSuccessful());
                if (response.isSuccessful()) {
                    Log.e(TAG, "uploadUri: " + response.body().getResult());
                }
            }

            @Override
            public void onFailure(Call<PODResponse> call, Throwable t) {
                Log.e(TAG, "onFailure:uploadUri " + t.getLocalizedMessage());
            }
        });

    }
}

I also tried this way but not getting success. Server is asking for "insert your image". please help me

@baguzajja
Copy link

If i look your code
from

MultipartBody.Part filePart = MultipartBody.Part.createFormData("uploadFile", file.getName(),
                RequestBody.create(MediaType.parse("image/*"), file));

use
MultipartBody.Part filePart = MultipartBody.Part.createFormData("filePart", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));

and

call for file with name
filePart

I hope work

@ghost
Copy link

ghost commented Nov 25, 2016

@ayon115 it solve my problem thank you very much, before i user @part("username") String username ,there are a exception JSON must start with an array or an object. but when i use your solution,just change String to RequestBoby,it help me .thank you

@ayon115
Copy link

ayon115 commented Jan 4, 2017

Glad to know it helped you :) @jounghu

@BabuinGH
Copy link

BabuinGH commented Jun 2, 2017

@ayon115 , I am having problem uploading a video to server using Retrofit2 multipart. Please could you help? I have posted a question in stackverflow. https://stackoverflow.com/questions/44319052/upload-video-using-retrofit2

@vivekkiran
Copy link
Author

Thank you, everyone, for your solutions, it helped me a lot and resolved my issues, this issue thread is a great guide for other developers facing similar issues.

@hb-vijaypalod
Copy link

hb-vijaypalod commented Dec 18, 2017

I need to upload file inside a JSON object like below.

[
  {
    "imageType": "image_type",
    "image": "imageObj",  //Image File Here
    "imageName": "abc1"
  },
  {
    "imageType": "image_type",
    "image": "imageObj", //Image File Here
    "imageName": "abc2"
  }
]

How to achieve this via retrofit 2.0.

@asywalulfikri
Copy link

How to upload image and content in the same time with retrofit use Oauth 1.0

@maheshsuthar93
Copy link

Hello any one can help me to upload audio file using retrofit i am not able to upload audio file and play it

@maheshsuthar93
Copy link

maheshsuthar93 commented Feb 2, 2018 via email

@fanshidong1993
Copy link

@markini thank u

@fanshidong1993
Copy link

fanshidong1993 commented Jul 17, 2018

来自中国的娃娃们,看这里。

@multipart
@post("/api/.../{id}/audio")
Call sendAudio(
@path("id") String id,
@part MultipartBody.Part part
);

RequestBody requestBody = RequestBody.create(MEDIA_TYPE_AUDIO, audioFile);
MultipartBody.Part part = MultipartBody.Part.createFormData("message_audio[audio]", audioFile.getName(), requestBody);
service.sendAudio(id, part)...

@markini 这位大佬的方案亲测有效。

@vj68
Copy link

vj68 commented Jan 2, 2020

Just in case anyone struggles with uploading an image via ImageField in Django,
change ImageField to FileField.
Doesn't work with ImageField.

@zzantares
Copy link

@rajvijay68 I belive ImageField will work if creating the RequestBody directly from the file, instead of using multipart form data. Anyways, just leaving this here for someone struggling too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests