Vark Vark - 1 year ago 159
HTTP Question

Sending image file with retrofit 2

I am trying to upload an image to our project's server using Retrofit 2

The image is picked through an image picking activity and seems to work since the file (image) can be displayed using Picasso.

Retrofit succeeds however the server doesn't seem to get the file.
Here is the server side part.

func (c *gin.Context) {
file, header , err := c.Request.FormFile("profileImage")
// err = http: no such file

Sever side error message

Even the RequestBody prints coherent information when I tested it (size, image type...)

Service :

Call<ResponseBody> modifyUserImage(@Part("profileImage") RequestBody profileImage, @Part("userID") RequestBody userID);

Following code is part of the same Fragment class

Opening image picking activity :

Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);

Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});

startActivityForResult(chooserIntent, 1);

On Activity Result:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK && requestCode == 1) {
// process the result
Uri selectedImage = data.getData();
String wholeID = DocumentsContract.getDocumentId(selectedImage);
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getContentResolver().
column, sel, new String[]{id}, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);

file = new File(filePath);

Request :

Call<ResponseBody> call = ServiceSingelton.getmInstance().getService()
.modifyUserImage(RequestBody.create(MediaType.parse("image/*"), file),
RequestBody.create(MediaType.parse("text/plain"), ServiceSingelton.getmInstance().getUserID()));

call.enqueue(new Callback<ResponseBody>() {
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.code() == 200) {
Log.d("RETROFIT SUCCESS", "Pic should be sent");
} else {
Log.d("RETROFIT SUCCESS", "Error code received modifying user");

public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("RETROFIT ERROR", t.getMessage());

Answer Source

Someone gave me this fix which worked :

To post a part with filename, you should change @Part("profileImage") RequestBody profileImage to @Part RequestBody profileImage, and pass it MultipartBody.Part.createFormData(partName, filename, requestBody):

// Service
Call<ResponseBody> modifyUserImage(@Part MultipartBody.Part profileImage, @Part("userID") RequestBody userID);

// Call
MultipartBody.Part imagePart = MultipartBody.Part.createFormData("profileImage", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<ResponseBody> call = ServiceSingelton.getmInstance().getService()
                                         RequestBody.create(MediaType.parse("text/plain"), ServiceSingelton.getmInstance().getUserID()));
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download