Retrofit 2 Multipart image upload with data
Solution 1
We test api in Postman... So my Create Post Answer includes (all Dynamic)
- Headers
- Simple Strings
- Single Image
- Array Of Images
- Array Of Categories
- Array Of Features
Almost all things
Below is the Postman image for api testing...
- Headers Image
So for this ... Below is my Api...
@POST("post-create")
Call<PostCreateResponse> getPostCreateBodyResponse(
@Header("Accept") String accept,
@Header("Authorization") String authorization,
@Body RequestBody file
);
Now Retrofit Client area--->
private Retrofit retrofit;
// This is Client
private RetrofitClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout(100, TimeUnit.SECONDS);
httpClient.readTimeout(100,TimeUnit.SECONDS);
httpClient.writeTimeout(100,TimeUnit.SECONDS);
httpClient.addInterceptor(logging); // <-- this is the important line!
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
This is the way I Made the Request...
/*
* -------------- Retrofit post Create single featured Image Working with MultipartBody -----------
* */
progressDialog.show();
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("title", "3 room Current Free")
.addFormDataPart("location", "Dhaka")
.addFormDataPart("latitude", "23.7515")
.addFormDataPart("longitude", "90.3625")
.addFormDataPart("condition", "1")
.addFormDataPart("rent_amount", "123456")
.addFormDataPart("is_negotiable", "0")
.addFormDataPart("available_from", "2018-10-15");
// Categories
for (int categoryId : categories) {
builder.addFormDataPart("categories[]", String.valueOf(categoryId));
}
// Features
for (Integer featureId : features) {
builder.addFormDataPart("features[]", String.valueOf(featureId));
}
// featured Image
if (photoPaths.get(0) != null) {
File featured_image = new File(photoPaths.get(0));
if (featured_image.exists()) {
// If you want to use Bitmap then use this
Bitmap bmp = BitmapFactory.decodeFile(featured_image.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);
builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, bos.toByteArray()));
// If you want to use direct file then use this ( comment out the below part and comment the above part )
//builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, featured_image));
}
}
// Images
for (String photoPath : photoPaths) {
if (photoPath != null) {
File images = new File(photoPath);
if (images.exists()) {
builder.addFormDataPart("images[]", images.getName(), RequestBody.create(MultipartBody.FORM, images));
}
}
}
RequestBody requestBody = builder.build();
Call<PostCreateResponse> call = RetrofitClient.getInstance().getApi().getPostCreateBodyResponse(Accept, Authorization, requestBody);
call.enqueue(new Callback<PostCreateResponse>() {
@Override
public void onResponse(Call<PostCreateResponse> call, Response<PostCreateResponse> response) {
progressDialog.dismiss();
Log.d(TAG, "onResponse: response code: retrofit: " + response.code());
}
@Override
public void onFailure(Call<PostCreateResponse> call, Throwable t) {
}
});
/*
* ---------------- Retrofit post Create single featured Image Working with MultipartBody----------------
* */
I hope this will help you all... thanks
Solution 2
get Image like this
Uri mImageUri = data.getData();
// Get the cursor
Cursor cursor = getContentResolver().query(mImageUri,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageURI = cursor.getString(columnIndex);
cursor.close();
File file = new File(mImageUri.getPath())
RequestBody reqFile = RequestBody.create(okhttp3.MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image",
file.getName(), reqFile);
Solution 3
This is my activity code where i am using multipart to show images, follow this code:
public void uploadimage()
{
String filePath = getRealPathFromURIPath(uri1, DriverDetails.this);
Log.d("hanish123456","File path-> "+filePath);
file1 = new File(filePath);
Log.d("uploadimage", "Filename " + profileimage1);
Bitmap bmp = BitmapFactory.decodeFile(file1.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("image", profileimage1,
RequestBody.create(MediaType.parse("image/*"), bos.toByteArray()));
RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), profileimage1);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(3, TimeUnit.MINUTES)
.readTimeout(3,TimeUnit.MINUTES)
.writeTimeout(3,TimeUnit.MINUTES).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(SERVER_PATH)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService uploadImage = retrofit.create(ApiService.class);
Log.d("uploadimage", fileToUpload+" "+filename);
Call<ProfileResponse> fileUpload = uploadImage.uploadFile(fileToUpload, filename);
fileUpload.enqueue(new Callback<ProfileResponse>() {
@Override
public void onResponse(Call<ProfileResponse> call, Response<ProfileResponse> response) {
if(response.isSuccessful()){
Toast.makeText(DriverDetails.this,"Successful "+ response.raw().message(), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(DriverDetails.this, response.raw().message(), Toast.LENGTH_LONG).show();
}
// Toast.makeText(MainActivity.this, "Success " + response.body().getSuccess(), Toast.LENGTH_LONG).show();
Log.d("uploadimage", "No Error ");
}
@Override
public void onFailure(Call<ProfileResponse> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
Log.d("uploadimage", "Error occur " + t.getMessage());
}
}
});
}
Wasi Sadman
Updated on November 23, 2020Comments
-
Wasi Sadman over 3 years
Hello everyone I want to post image and other data through Retrofit2. I am sending data with one image.
All the other info is storing but my image is not storing.while i am testing with postman, it works.
please guide me where I am lacking in my code
This is the postman code snippet that works
OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"); RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\[email protected]\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n123456\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTest\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"phone\"\r\n\r\n1234567890\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"03.JPG\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"); Request request = new Request.Builder() .url("https://"url"/api/v1/sign-up") .post(body) .addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW") .addHeader("cache-control", "no-cache") .addHeader("postman-token", "2dd038d9-5f52-fcd0-9331-445eaf35c230") .build(); Response response = client.newCall(request).execute();
Below is the postman request image:
this is my Retrofit api
@Multipart @POST("sign-up") Call<SignUpResponse> getSignUpResponse( @Part("email") RequestBody email, @Part("password") RequestBody password, @Part("name") RequestBody name, @Part("phone") RequestBody phone, @Part MultipartBody.Part image //@Part("image") RequestBody image // i have thried them both but they didnt work //@Part("image\"; filename=\"pp.jpg\" ") RequestBody image );
this is my client area:
private RetrofitClient() { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); httpClient.addInterceptor(logging); // <-- this is the important line! retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(httpClient.build()) .build(); }
and this is the part where i am making the request:
RequestBody namePart = RequestBody.create(MultipartBody.FORM, "nameasd"); RequestBody emailPart = RequestBody.create(MultipartBody.FORM, "[email protected]"); RequestBody mobilePart = RequestBody.create(MultipartBody.FORM, "123456623"); RequestBody passwordPart = RequestBody.create(MultipartBody.FORM, "123456123"); //String filepath = "/storage/0403-0201/DCIM/Camera/20180926_203219.jpg"; this is the image source File file = new File(filepath); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); //RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("image",file.getName(),reqFile); Call<SignUpResponse> call = RetrofitClient.getInstance().getApi().getSignUpResponse(emailPart, passwordPart, namePart, mobilePart, body); call.enqueue(new Callback<SignUpResponse>() { @Override public void onResponse(Call<SignUpResponse> call, Response<SignUpResponse> response) { progressDialog.dismiss(); Log.d(TAG, "onResponse: "+response.body()); Log.d(TAG, "onResponse: meta: " + response.body().getMeta().getStatus()); } @Override public void onFailure(Call<SignUpResponse> call, Throwable t) { Toast.makeText(SignupActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show(); Log.d(TAG, "onFailure: "+t.getMessage()); } });
this is the code where i get the data
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // get selected images from selector if (requestCode == REQUEST_CODE) { if (resultCode == RESULT_OK) { mResults = data.getStringArrayListExtra(SelectorSettings.SELECTOR_RESULTS); imagePath = mResults.get(0); Glide.with(SignupActivity.this) .load(mResults.get(0)) .into(profileImage); } } super.onActivityResult(requestCode, resultCode, data); }
I even set it on a view and that works...
-
Wasi Sadman over 5 yearsi think here "companyLogo" should be "image" in my case?
-
Wasi Sadman over 5 yearsi have already tried "multipart/form-data"... it is not working for me...
-
s.j over 5 yearsto check in postman simply add your base url following with Api service post request. in postman body add key values to get data in this format { "id":"1", "user_type":"1" }
-
Wasi Sadman over 5 yearsLog.d("uploadimage", "Filename " + profileimage1); what is your profileimage1? is it a path or file?
-
Bhuvaneshwaran Vellingiri over 5 yearsRequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); this should work
-
Wasi Sadman over 5 yearsString filepath = "/storage/0403-0201/DCIM/Camera/20180926_203219.jpg"; i have hard-coded the file path. it it wrong?
-
Wasi Sadman over 5 yearsRequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); i have already tried it. it is not wotking @BhuvaneshwaranVellingiri
-
s.j over 5 yearsits variable defined in activity to get image.
-
Wasi Sadman over 5 yearssthill facing the sam problem... image is not storing
-
Archu Mohan over 5 yearsuse okhttp3 in mediatype
-
Ibrahim Sušić about 5 years@Body parameters cannot be used with form or multi-part encoding.
-
Wasi Sadman about 5 yearsCan you please explain why it cannot be used with form or multi-part encoding? @IbrahimSušić
-
Ibrahim Sušić about 5 yearsSorry my wrong , I was implemented in network @Multipart . That made me a problem. Thank you for answer :)
-
sanjana over 3 yearsHow to send arraylist containing image nd string in obj ??
-
Rahul Pandey almost 2 years@sanjana did you get the answer ? and what library did you use?, Retrofit or volley