Send Form data to server in Retrofit - java

Trying to send form data to the server via Retrofit but unable to request to the server. I want to post an image array with their data.
val builder: MultipartBody.Builder = MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("device_id",device_UDID)
builder.addFormDataPart("device_token",device_token)
builder.addFormDataPart("device_type","android")
builder.addFormDataPart("country_code",Constant.COUNTRY_CODE)
builder.addFormDataPart("email",signUpBean.email)
builder.addFormDataPart("mobile",signUpBean.phoneNumber)
builder.addFormDataPart("first_name",signUpBean.firstName)
builder.addFormDataPart("last_name",signUpBean.lastName)
builder.addFormDataPart("gender",signUpBean.gender)
builder.addFormDataPart("dob",signUpBean.dob)
builder.addFormDataPart("city",signUpBean.city)
builder.addFormDataPart("bike_type_id","1")
builder.addFormDataPart("bike_model",signUpBean.mfg)
builder.addFormDataPart("bike_manufacturer",signUpBean.mfg)
builder.addFormDataPart("reg_year",signUpBean.mfgYear)
builder.addFormDataPart("liecense_plate",signUpBean.licencePlateNo)
builder.addFormDataPart("bank_ac_name",signUpBean.bnkHolderName)
builder.addFormDataPart("bank_ac_number",signUpBean.bnkAccountNumber)
builder.addFormDataPart("bank_name",signUpBean.bnkName)
builder.addFormDataPart("bank_ifsc_code",signUpBean.ifscCode)
builder.addFormDataPart(
"profile_pic",
"profile" + ".jpg",
RequestBody.create(MediaType.parse("image/*"), file_profile!!)
)
builder.addFormDataPart(
"provider_documents[0][document]",
"1" + ".jpg",
RequestBody.create(MediaType.parse("image/*"), file_profile!!)
)
builder.addFormDataPart("provider_documents[0][document_id]","1")
builder.addFormDataPart("provider_documents[0][unique_id]","1")
builder.addFormDataPart("provider_documents[0][exprice_at]","2010-12-12")
val requestBody = builder.build()
observable = apiInterface.signUp2(requestBody)
I have tried many solutions but unable to post an image array with their data.
When i remove provider_documents from addFormDataPart it works fine.
// #Multipart
#POST(URLHelper.register)
fun signUp2(#Body builder: RequestBody ): Observable<Registration>
How can I send Providers_document array and it is working fine on Postman.
post this type of data from retrofit
val partMap = HashMap<String, RequestBody>()
partMap.put("device_id", createPartFromString(device_UDID));
partMap.put("device_token",createPartFromString(device_token))
partMap.put("device_type",createPartFromString("android"))
partMap.put("country_code",createPartFromString(Constant.COUNTRY_CODE))
partMap.put("email",createPartFromString(signUpBean.email))
partMap.put("mobile",createPartFromString(signUpBean.phoneNumber))
partMap.put("first_name",createPartFromString(signUpBean.firstName))
partMap.put("last_name",createPartFromString(signUpBean.lastName))
partMap.put("gender",createPartFromString(signUpBean.gender))
partMap.put("dob",createPartFromString(signUpBean.dob))
partMap.put("city",createPartFromString(signUpBean.city))
partMap.put("bike_type_id",createPartFromString("1"))
partMap.put("bike_model",createPartFromString(signUpBean.mfg))
partMap.put("bike_manufacturer",createPartFromString(signUpBean.mfg))
partMap.put("reg_year",createPartFromString(signUpBean.mfgYear))
partMap.put("liecense_plate",createPartFromString(signUpBean.licencePlateNo))
partMap.put("bank_ac_name",createPartFromString(signUpBean.bnkHolderName))
partMap.put("bank_ac_number",createPartFromString(signUpBean.bnkAccountNumber))
partMap.put("bank_name",createPartFromString(signUpBean.bnkName))
partMap.put("bank_ifsc_code",createPartFromString(signUpBean.ifscCode))
partMap.put(
"provider_documents["+0+"][document_id]",
createPartFromString(signUpBean.ifscCode)
)
partMap.put(
"provider_documents["+0+"][unique_id]",
createPartFromString(signUpBean.ifscCode)
)
partMap.put(
"provider_documents["+0+"][exprice_at]",createPartFromString(signUpBean.dob)
)
val ImageMap = HashMap<String, MultipartBody.Part>()
ImageMap.put("profile_pic", prepareFilePart("12", file_profile!!));
ImageMap.put("provider_documents["+0+"][document]", prepareFilePart("1", file_profile!!));
Request Api
#Multipart
#POST(URLHelper.register)
fun signUp3(
#PartMap photo: HashMap<String,
RequestBody>,
#PartMap ImageMap:HashMap<MultipartBody.Part>,
): Observable<Registration>

Dummy api interface.
public interface ApiInterface {
#Multipart
#POST(URLHelper.register)
Call<ModelProp> signUp2(#Part List<MultipartBody.Part> photos,
#PartMap Map<String, RequestBody> map;
}
Now create data to post like this.
Map<String, RequestBody> partMap = new HashMap<>();
List<MultipartBody.Part> images = new ArrayList<>();
partMap.put("device_id", createPartFromString(deviceId)); // add data which are common for all images like device_id, device_token, device_type etc.
..
..
for (int i=0; i < upFileList.size(); i++){
images.add(prepareFilePart("provider_documents["+i+"][document]", imageFile));
partMap.add("provider_documents["+i+"][expires_at]", createPartFromString(expiry)); // add image specific data.
...
..
}
...
..
observable = apiInterface.signUp2(images, partMap).
createPartFromString method
public RequestBody createPartFromString(String string) {
return RequestBody.create(MultipartBody.FORM, string);
}
prepareFilePart method
private MultipartBody.Part prepareFilePart(String partName, File file){
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
return MultipartBody.Part.createFormData(partName, file.getName(),requestBody);
}

Use it Like this:-
// #Multipart
#POST(URLHelper.register)
fun signUp2(#Part builder: MultipartBody ): Observable<Registration>
Updated :-
private void uploadToServer(String filePath) {
showProgressDialog();
Retrofit retrofit = RetrofitClient.getRetrofitClient(this);
ApiInterface uploadAPIs = retrofit.create(ApiInterface.class);
File file = new File(filePath);
//compressor.setDestinationDirectoryPath()
RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("fileUpload", file.getName(), fileReqBody);
//RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "image-type");
RequestBody imgNameReqBody = RequestBody.create(MediaType.parse("multipart/form-data"), "B2B_" + System.nanoTime());
uploadAPIs.uploadImage(imgNameReqBody, part).enqueue(new Callback<UploadImageRespose>() {
#Override
public void onResponse(#NonNull Call<UploadImageRespose> call, #NonNull retrofit2.Response<UploadImageRespose> response) {
if (response.isSuccessful() && response.body() != null) {
if (response.body().getCODE().equalsIgnoreCase("SUCCESS")) {
Toast.makeText(Activity.this, "Profile Image Upload Succesfully", Toast.LENGTH_SHORT).show();
} else {
hideProgressDialog();
Toast.makeText(Activity.this, "Some Error occurred, try again", Toast.LENGTH_SHORT).show();
}
} else {
hideProgressDialog();
}
}
#Override
public void onFailure(#NonNull Call<UploadImageRespose> call, #NonNull Throwable t) {
Timber.d(TAG, t.getMessage());
hideProgressDialog();
Toast.makeText(Activity.this, "Some Error occurred, try again", Toast.LENGTH_SHORT).show();
}
});
}
add below method in your interface:-
#Multipart
#POST("Your Path Here")
Call<UploadImageRespose> uploadImage(#Part("img_name") RequestBody img_name,
#Part MultipartBody.Part file);

Related

400 Error when uploading file on server with auth token headers using Retrofit Android

public void uploadFile(String token, String org, String fileName){
if(!ConnectionUtility.isNetworkAvailable2(getmContext())){
return;
}
retryTrigger = false;
File file = new File(fileName);
String fName = file.getName();
RequestBody fb = RequestBody.create(file, MediaType.parse("application/pdf"));
MultipartBody .Part body =
MultipartBody.Part.createFormData("uploadFile", fName, fb );
Map<String,String> headerMap = new HashMap<>();
headerMap.put("User-Agent", "KMP");
headerMap.put("X-Auth-Token", token);
headerMap.put("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundarytkRt9rKilDJeeFe1");
headerMap.put("accept", "application/json");
headerMap.put("Csrf-Token", "nocheck");
mCompositeDisposables.add(mKcpsLoginApiInterface.getFileUrl(org,headerMap,body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry(1, throwable -> {
retryTrigger = true;
return false;
})
.subscribeWith(new DisposableSingleObserver<Response<GetFileUrl>>() {
#Override
public void onSuccess(#NonNull Response<GetFileUrl> getFileUrlResponse) {
// Always get 400 error
}
#Override
public void onError(#NonNull Throwable e) {
}
})
);
}
My Interface looks like this
#Multipart
#POST("/o/{org}/files")
Single<Response<GetFileUrl>> getFileUrl(#Path("org") String org,
#HeaderMap Map<String,String> headers,
#Part MultipartBody.Part file
);
Additional Info:
I've used the correct token and headers using swagger site and it works but when somehow I code it on my project, it won't work. Insights would be much appreciated.
I always seem to get 400 error response code.
Thank you

How to post text data, single image and multiple image in single POST method using retrofit in Android?

I am using retrofit to post text data, single image and multiple image in single POST request. I tried some method but they did not work form me. I've attached PostMan screenshot and previous code I have done below.
Postman screenshot
Sample code i've tried :
apiInterface class :
public interface PostSurveyFormApiInterface {
#Multipart
#POST("Shared/InsertDirectSurveyAsync")
Call<ResponseBody> postDirectSurveyForm(#Header("Authorization") String auth,
#Header("Content-Type") String contentType,
#Part("CompanyName") RequestBody companyName,
#Part("Address") RequestBody address,
#Part MultipartBody.Part digitalStamp,
#Part MultipartBody.Part digitalSignature,
#Part MultipartBody.Part[] surveyImage);
}
method to post data:
private void postDataToServer(List<Uri> paths){
RequestBody companyName = RequestBody.create(MediaType.parse("text/plain"), edtCompanyName.getText().toString().trim());
RequestBody address = RequestBody.create(MediaType.parse("text/plain"), edtCompanyAddress.getText().toString());
//for single stamp image
File fileStamp = new File(getRealPathFromURI(stampUri));
RequestBody requestBodyStamp = RequestBody.create(MediaType.parse("image/*"),fileStamp);
MultipartBody.Part stampImagePart = MultipartBody.Part.createFormData("DigitalStamp",
fileStamp.getName(),
requestBodyStamp);
//for single signature image
File fileSignature = new File(getRealPathFromURI(signatureUri));
RequestBody requestBodySignature = RequestBody.create(MediaType.parse("image/*"),fileSignature);
MultipartBody.Part signatureImagePart = MultipartBody.Part.createFormData("DigitalSignature",
fileSignature.getName(),
requestBodySignature);
//for multiple survey(files) images
MultipartBody.Part[] surveyImagesParts = new MultipartBody.Part[paths.size()];
for (int index = 0; index < paths.size(); index++) {
Log.v(TAG,"survey image path \n"+getRealPathFromURI(paths.get(index)));
File file = new File(getRealPathFromURI(paths.get(index)));
RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file);
surveyImagesParts[index] = MultipartBody.Part.createFormData("Files", file.getName(), surveyBody);
}
PostSurveyFormApiInterface apiInterface = ApiClient.getApiClient().create(PostSurveyFormApiInterface.class);
apiInterface.postDirectSurveyForm(
getToken(),
"application/json",
companyName,
address,
stampImagePart,
signatureImagePart,
surveyImagesParts
).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
progressDialog.dismiss();
if (response.isSuccessful()){
Log.v(TAG,"response successful");
}else{
Log.v(TAG,"failed to post data");
Log.v(TAG,"error : "+response.toString());
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
progressDialog.dismiss();
Log.e(TAG,"error : "+t.getMessage());
}
});
}
Please help me guys I am trying this from last 3 days but can not fix.
Thanks in Advance.
After long research following codes works for me...
PostSurveyFormApiInterface
public interface PostSurveyFormApiInterface {
#Multipart
#POST("Shared/InsertDirectSurveyMobileAsync")
Call<ResponseBody> postDirectSurveyForm(#Header("Authorization") String auth,
#Part("CompanyName") RequestBody companyName,
#Part("CompanyAddress") RequestBody address,
#Part MultipartBody.Part digitalStamp,
#Part MultipartBody.Part digitalSignature,
#Part List<MultipartBody.Part> files);
}
Method to post data
private void postDataToServer(List<Uri> paths) {
// Request body for Text data (CompanyName)
RequestBody companyName = RequestBody.create(MediaType.parse("text/plain"), edtCompanyName.getText().toString().trim());
// Request body for Text data (Company Address)
RequestBody companyAddress = RequestBody.create(MediaType.parse("text/plain"), edtCompanyAddress.getText().toString().trim());
// Multipart request for single image (Digital Stamp)
MultipartBody.Part digitalStampPart = prepareFilePart("DigitalStamp",stampUri);
// Multipart request for single image (Digital Signature)
MultipartBody.Part digitalSignaturePart = prepareFilePart("DigitalSignature",signatureUri);
//Multipart request for multiple files
List<MultipartBody.Part> listOfPartData = new ArrayList<>();
if (paths != null) {
for (int i = 0; i < paths.size(); i++) {
listOfPartData.add(prepareFilePart("Files[]",paths.get(i)));
}
}
PostSurveyFormApiInterface apiInterface = ApiClient.getApiClient().create(PostSurveyFormApiInterface.class);
apiInterface.postDirectSurveyForm(
getToken(),
companyName,
companyAddress,
digitalStampPart,
digitalSignaturePart,
listOfPartData
).enqueue(new Callback<SurveyPostResponse>() {
#Override
public void onResponse(Call<SurveyPostResponse> call, Response<SurveyPostResponse> response) {
if (response.isSuccessful()) {
Log.v(TAG, "response successful");
} else {
Log.v(TAG, "failed to post data");
}
}
#Override
public void onFailure(Call<SurveyPostResponse> call, Throwable t) {
t.printStackTrace();
Log.e(TAG, "error : " + t.getMessage());
}
});
}
PrepareFilePart method :
#NonNull
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
// use the FileUtils to get the actual file by uri
//File file = FileUtils.getFile(this, fileUri);
File file = new File(getRealPathFromUri(mContext, fileUri));
// create RequestBody instance from file
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);
// MultipartBody.Part is used to send also the actual file name
return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}
getRealPathFromUri method:
// Get Original image path
public static String getRealPathFromUri(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = context.getContentResolver().query(contentUri, proj, null,null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}

Sending multiple images using retrofit in a single key

I have tried all the methods available on the internet but nothing is working for me.
I'm trying to send images in a Single Key Value
{
files[]
}
This is my interface
public interface UserClient {
#Multipart
#POST(".")
Call<JsonElement> upload(
#Part("text") RequestBody text,
#Part("image") RequestBody image,
#Part("login") RequestBody login,
#Part List<MultipartBody.Part> files
);
}
this is my upload Method
public void uploadFiles(String text) {
QBUser user = SharedPrefsHelper.getInstance().getQbUser();
String userName = user.getFullName();
String image = "https://image.flaticon.com/icons/svg/146/146031.svg";
String URL = URLs.URL_POST + user.getPhone() + "/";
RequestBody textPart = RequestBody.create(MultipartBody.FORM, text);
RequestBody imagePart = RequestBody.create(MultipartBody.FORM, image);
RequestBody loginPart = RequestBody.create(MultipartBody.FORM, userName);
//list of files
List<MultipartBody.Part> filesList = new ArrayList<>();
for (int i = 0; i < arrayList_FilePath.size(); i++) {
filesList.add(prepareFilePart("files" + i, arrayList_FilePath.get(i)));
}
//Create retrofit instance
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
UserClient client = retrofit.create(UserClient.class);
Log.i(TAG, "uploadFiles: " + filesList);
Call<JsonElement> call = client.upload(textPart, imagePart, loginPart, filesList);
call.enqueue(new Callback<JsonElement>() {
#Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
finish();
Toast.makeText(getApplicationContext(), "Successful: " + response.message(),
Toast.LENGTH_LONG).show();
Log.i(TAG, "onResponse: " + response.body() + response.message());
}
#Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Toast.makeText(getApplicationContext(), "failed", Toast.LENGTH_LONG).show();
}
});
}
This is preparefilePart Method
public MultipartBody.Part prepareFilePart(String partName, String path){
long imagename = System.currentTimeMillis();
File file = new File(path);
RequestBody requestBody = RequestBody.create(
MediaType.parse("image/*"),
file
);
return MultipartBody.Part.createFormData(partName, imagename + ".jpeg" ,requestBody);
}
If I send only text request without images its working fine but when i send image it's not working
it's giving an error Code 500 Internal Server Error with null response in body
Note: Api is working Great in Postman
file was not uploading because file was not Creating Properly
thanks to github i found a way to create a file Properly
GitHub link for creating file
Also Made a little bit of changes in my code according to this answer
link for stackoverflow answer

How to Fix server error 500 when send a Multipart file in retorfit android

I am uploading files using retrofit but there is a server error when POST the file with the data
The Post man Request is working an uploading the files but when it comes to andoid it's return a server error 500
Here is where I upload the files
HashMap<String, Object> map = new HashMap<>();
map.put("s_name", name);
map.put("s_file_number", fileNumber);
map.put("fk_i_extension_id", 3);
map.put("fk_i_project_id", 1);
map.put("s_description", description);
map.put("fk_i_type_id", 6);
map.put("b_secret", 1);
map.put("fk_i_category_id", 60);
map.put("s_file", s_file.headers());
map.put("s_attachments", listOfFilePart);
Call<ArchiverMainObject> fileCall = ArchiveApplication.apiRequests.addFile(token, map);
fileCall.enqueue(new Callback<ArchiverMainObject>() {
#Override
public void onResponse(Call<ArchiverMainObject> call, Response<ArchiverMainObject> response) {
f (response.errorBody() != null) {
JSONObject jsonObject = null;
try {
jsonObject =
new JSONObject(response.errorBody().string());
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ArchiverMainObject> call, Throwable t) {
Log.d(TAG, "onResponse: addFile error " + t.getMessage());
}
});
}
The File converter
#NonNull
private MultipartBody.Part prepareFilePart(String partName, String url) {
java.io.File file = new java.io.File(url);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
return MultipartBody.Part.createFormData(partName, file.getName(),
requestFile);
}
The ClientAPi
#Multipart
#POST("files/new")
Call<ArchiverMainObject> addFile(
#Header("Authorization") String token,
#PartMap Map<String, Object> newFile);
this is the error part of the code:
{"status":{"success":false,"message":"Undefined variable:
fileName","status_code":500},"debug":
I Solve it by edit the api interface method by sperate the mutlipart from the map
From this:
#Multipart
#POST("files/new")
Call<ArchiverMainObject> addFile(
#Header("Authorization") String token,
#PartMap Map<String, Object> newFile);
To this:
#Multipart
#POST("files/new")
Call<ArchiverMainObject> addFile(
#Header("Authorization") String token,
#PartMap Map<String, Object> newFile,
#Part MultipartBody.Part file);

How to send Audio File Using Retrofit

I am Trying to send audio file using Retrofit but ResponseBody always null and Status is 500 internal server error ,I tried a lot of different things but nothing Works
Postman Screenshots:
body
header
My Client:
public class AudioClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(context.getString(R.string.base_url)).client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
addAudioComment method:
#Multipart
#POST("api/Comment/AddSoundComment")
Call<AudioComment> addAudioComment(#Header("Authorization") String contentRange,
#Part("referenceType") RequestBody ReferenceType,
#Part("referenceId") RequestBody ReferenceID,
#Part("parentId") RequestBody ParentID,
#Part MultipartBody.Part AudioComment);
The Request :
File audioFile = new File(mRecordedFilePath);
RequestBody reqFile = RequestBody.create(MediaType.parse("audio/*"), audioFile);
audioPart = MultipartBody.Part.createFormData("AudioComment", audioFile.getName(), reqFile);
Call<AudioComment> apiCall = service.addAudioComment(String.valueOf(SharedPreferencesHelper.getLogInToken(CommentsActivity.this)),
reqRefType, reqRefId, reqParentId, audioPart);
//apiCall =service.addAudioComment();
apiCall.enqueue(new Callback<AudioComment>() {
#Override
public void onResponse(Call<AudioComment> call, Response<AudioComment> response) {
Log.i("RETROFIT", "onResponse Called");
AudioComment postResult = response.body();
}
#Override
public void onFailure(Call<AudioComment> call, Throwable t) {
String err = t.getMessage() == null ? "" : t.getMessage();
showError(R.string.service_failure);
Log.e("RETROFIT", err);
setRefreshing(false);
dismissProgress();
}
});
In my case I remove #Multipart from interface and replaced
#part with #Body RequestBody requestBody. Eg. as follows,the second parameter is audio file.
public interface APIInterface {
#POST(url)
Call<String> postAudioAndGetResponse(#Header("Subscription-Key") String keyValue,
#Body RequestBody requestBody,
#Query("language") String language);
}
and called above method like this
File file = new File(audioFileName);
RequestBody requestBody = RequestBody.create(MediaType.parse("audio/*"), file);
Call<String> str = apiInterface.postAudioAndGetResponse(speechSubscriptionKey, requestBody,"en-IN");
and it worked .
Hope it will help someone. :)

Categories