POST Multipart Form Data using Retrofit 2.0 including image POST Multipart Form Data using Retrofit 2.0 including image android android

POST Multipart Form Data using Retrofit 2.0 including image


There is a correct way of uploading a file with its name with Retrofit 2, without any hack:

Define API interface:

@Multipart@POST("uploadAttachment")Call<MyResponse> uploadAttachment(@Part MultipartBody.Part filePart);                                    // You can add other parameters too

Upload file like this:

File file = // initialize file hereMultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));Call<MyResponse> call = api.uploadAttachment(filePart);

This demonstrates only file uploading, you can also add other parameters in the same method with @Part annotation.


I am highlighting the solution in both 1.9 and 2.0 since it is useful for some

In 1.9, I think the better solution is to save the file to disk and use it as Typed file like:

RetroFit 1.9

(I don't know about your server-side implementation) have an API interface method similar to this

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

And use it like

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

For RetroFit 2 Use the following method

RetroFit 2.0 ( This was a workaround for an issue in RetroFit 2 which is fixed now, for the correct method refer jimmy0251's answer)

API Interface:

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

Use it like:

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


I used Retrofit 2.0 for my register users, send multipart/form File image and text from register account

In my RegisterActivity, use an AsyncTask

//AsyncTaskprivate class Register extends AsyncTask<String, Void, String> {    @Override    protected void onPreExecute() {..}    @Override    protected String doInBackground(String... params) {        new com.tequilasoft.mesasderegalos.dbo.Register().register(txtNombres, selectedImagePath, txtEmail, txtPassword);        responseMensaje = StaticValues.mensaje ;        mensajeCodigo = StaticValues.mensajeCodigo;        return String.valueOf(StaticValues.code);    }    @Override    protected void onPostExecute(String codeResult) {..}

And in my Register.java class is where use Retrofit with synchronous call

import android.util.Log;import com.tequilasoft.mesasderegalos.interfaces.RegisterService;import com.tequilasoft.mesasderegalos.utils.StaticValues;import com.tequilasoft.mesasderegalos.utils.Utilities;import java.io.File;import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.RequestBody;import okhttp3.ResponseBody;import retrofit2.Call; import retrofit2.Response;/**Created by sam on 2/09/16.*/public class Register {public void register(String nombres, String selectedImagePath, String email, String password){    try {        // create upload service client        RegisterService service = ServiceGenerator.createUser(RegisterService.class);        // add another part within the multipart request        RequestBody requestEmail =                RequestBody.create(                        MediaType.parse("multipart/form-data"), email);        // add another part within the multipart request        RequestBody requestPassword =                RequestBody.create(                        MediaType.parse("multipart/form-data"), password);        // add another part within the multipart request        RequestBody requestNombres =                RequestBody.create(                        MediaType.parse("multipart/form-data"), nombres);        MultipartBody.Part imagenPerfil = null;        if(selectedImagePath!=null){            File file = new File(selectedImagePath);            Log.i("Register","Nombre del archivo "+file.getName());            // create RequestBody instance from file            RequestBody requestFile =                    RequestBody.create(MediaType.parse("multipart/form-data"), file);            // MultipartBody.Part is used to send also the actual file name            imagenPerfil = MultipartBody.Part.createFormData("imagenPerfil", file.getName(), requestFile);        }        // finally, execute the request        Call<ResponseBody> call = service.registerUser(imagenPerfil, requestEmail,requestPassword,requestNombres);        Response<ResponseBody> bodyResponse = call.execute();        StaticValues.code  = bodyResponse.code();        StaticValues.mensaje  = bodyResponse.message();        ResponseBody errorBody = bodyResponse.errorBody();        StaticValues.mensajeCodigo  = errorBody==null                ?null                :Utilities.mensajeCodigoDeLaRespuestaJSON(bodyResponse.errorBody().byteStream());        Log.i("Register","Code "+StaticValues.code);        Log.i("Register","mensaje "+StaticValues.mensaje);        Log.i("Register","mensajeCodigo "+StaticValues.mensaje);    }    catch (Exception e){        e.printStackTrace();    }}}

In the interface of RegisterService

public interface RegisterService {@Multipart@POST(StaticValues.REGISTER)Call<ResponseBody> registerUser(@Part MultipartBody.Part image,                                @Part("email") RequestBody email,                                @Part("password") RequestBody password,                                @Part("nombre") RequestBody nombre);}

For the Utilities parse ofr InputStream response

public class Utilities {public static String mensajeCodigoDeLaRespuestaJSON(InputStream inputStream){    String mensajeCodigo = null;    try {        BufferedReader reader = new BufferedReader(                new InputStreamReader(                    inputStream, "iso-8859-1"), 8);        StringBuilder sb = new StringBuilder();        String line;        while ((line = reader.readLine()) != null) {            sb.append(line).append("\n");        }        inputStream.close();        mensajeCodigo = sb.toString();    } catch (Exception e) {        Log.e("Buffer Error", "Error converting result " + e.toString());    }    return mensajeCodigo;}}