Image uploading with other parameters Android - java

I want to upload image on retrofit API with other 5 parameters, I tried all methods listed on stackoverflow but didn't succeed. I'm getting 500 Internal Server Error and {"message":"Unexpected token - in JSON at position 0"} this repsonse from server. I tried this in POSTMAN but API is working fine in it. Can you please tell me where I'm doing wrong.
Interface Code.
#Multipart
#Headers({"Content-Type: application/json;charset=UTF-8"})
#POST("uploaddoc")
Call<UploadDocuments> uploadDocuments(#PartMap Map<String, RequestBody> requestBodyMap,
#Part MultipartBody.Part file,
#Header("Authorization") String auth);
API call in activity.
private void uploadImage(String imagePath) {
File file = new File(imagePath);
RequestBody requestFile = RequestBody.create(file, MediaType.parse("multipart/form-data"));
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
Map<String, RequestBody> requestBodyMap = new HashMap<>();
requestBodyMap.put("label", RequestBody.create(encryptedLabel, MediaType.parse("multipart/form-data")));
requestBodyMap.put("role", RequestBody.create(encryptedRole, MediaType.parse("multipart/form-data")));
requestBodyMap.put("userobjid", RequestBody.create(encryptedUserObjId, MediaType.parse("multipart/form-data")));
requestBodyMap.put("whichtype", RequestBody.create(encryptedWhichType, MediaType.parse("multipart/form-data")));
requestBodyMap.put("gsttype", RequestBody.create(encryptedGstinSpinner, MediaType.parse("multipart/form-data")));
Call<UploadDocuments> documentsCall = equibiz_api_interface.uploadDocuments(requestBodyMap, body,"Bearer " + AuthToken);
documentsCall.enqueue(new Callback<UploadDocuments>() {
#Override
public void onResponse(#NotNull Call<UploadDocuments> call, #NotNull Response<UploadDocuments> response) {
UploadDocuments uploadDocuments1 = response.body();
assert uploadDocuments1 != null;
if(response.isSuccessful())
Toast.makeText(VerificationActivity.this, response.message(), Toast.LENGTH_SHORT).show();
else{
try {
assert response.errorBody() != null;
Toast.makeText(VerificationActivity.this, response.errorBody().string(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(#NotNull Call<UploadDocuments> call, #NotNull Throwable t) {
if (t instanceof SocketTimeoutException)
Toast.makeText(VerificationActivity.this, "Socket Time out. Please try again.", Toast.LENGTH_LONG).show();
else
Toast.makeText(VerificationActivity.this, t.toString(), Toast.LENGTH_LONG).show();
}
});
}
Postman Screenshot (Authorization token added into Header part)

I had gone through the Postman screenshot and your code. The code has some problems. Here are the problems and solutions.
The field name for the image/file is documentimages, not file. Change the field name like below.
RequestBody requestFile = RequestBody.create(file, MediaType.parse("multipart/form-data"));
MultipartBody.Part body = MultipartBody.Part.createFormData("documentimages", file.getName(), requestFile);
//^^^^^^ NOTICE THE CHANGES HERE
For text fields (the data you send along with file) set MediaTye as text/plain instead of multipart/form-data. For example,
requestBodyMap.put("gsttype", RequestBody.create(encryptedGstinSpinner, MediaType.parse("text/plain")));
Like the above shown, you need to change it to other text fields as well.
The headers you were using is not correct. If you use #Headers({"Content-Type: application/json;charset=UTF-8"}) as content type here, the Retrofit assumes that the data you send from client to server is JSON, not Multipart Form Data. If you get JSON as the response for the uploaded file from the server, then you can do it like below.
#Multipart
#Headers({"Accept: application/json;"}) // <===== CHANGE HEADER TYPE FROM Content-Tye to Accept
#POST("uploaddoc")
Call<UploadDocuments> uploadDocuments(#PartMap Map<String, RequestBody> requestBodyMap,
#Part MultipartBody.Part file,
#Header("Authorization") String auth);
Check the header part.
If you want to understand more about the headers, refer to this thread

Related

why cant upload image using multipart?

i have problem with uploading image to server using multipart when uploading the image to sever the response is success but it get with null response and nothing uploaded when i trying to send data without using multipart send email or name data sent successfully but when i try to sent anything using part nothing sent to the server in the same api
#Multipart
#Headers({
"Content-Type: application/json",
"X-Requested-With: XMLHttpRequest"})
#POST("profile")
Call<ResponseBody> upload(
#Header("Authorization") String authorization,
#Part MultipartBody.Part image
);
void data_1(File file) {
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
Retrofit retrofits = new Retrofit.Builder().baseUrl(Base_url).
addConverterFactory(GsonConverterFactory.create()).build();
networkis networkis = retrofits.create(www.gift_vouchers.com.NetworkLayer.networkis.class);
Call<ResponseBody> call = networkis.upload("Bearer " + new saved_data().get_token(UserInfoModelViewFactory.context)
, body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
new utils().dismiss_dialog(UserInfoModelViewFactory.context);
Log.e("response_is", "" + response.message() + "dcd" + response.isSuccessful());
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
new utils().dismiss_dialog(UserInfoModelViewFactory.context);
Log.e("error", t.getMessage());
}
});
}

Getting error on updating details if the user won't update the image in Android Studio

I have this fragment UserProfileFragment.java, Here I have a form with some fields also with one user profile Image-view where the user uploads its image, initially everything works fine but when the user wants to update the details after fetching its data from the server also fetching and setting the thumbnail of image on image-view, Here when the user updates the details without changing the current profile image of Image-view the app crashes giving the error as follows:
FATAL EXCEPTION: main
Process: com.***.******, PID: 16313
java.lang.NullPointerException
at java.io.File.<init>(File.java:283)
at com.***.*****.fragment.UserProfileFragment.Updatemyprofile(UserProfileFragment.java:576)
at com.***.*****.fragment.UserProfileFragment.onClick(UserProfileFragment.java:343)
When the user changes the profile image the app won't crash while updating.
My update user method as follows:
private void Updatemyprofile() {
//pass it like this
File file = new File(picturePath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
// add another part within the multipart request
RequestBody userid = RequestBody.create(MediaType.parse("multipart/form-data"), Constant.Userid);
RequestBody role = RequestBody.create(MediaType.parse("multipart/form-data"), Constant.Role);
RequestBody name = RequestBody.create(MediaType.parse("multipart/form-data"), edtfullName.getText().toString().trim());
RequestBody pincode = RequestBody.create(MediaType.parse("multipart/form-data"), edtpincode.getText().toString().trim());
RequestBody address = RequestBody.create(MediaType.parse("multipart/form-data"), edtaddress.getText().toString().trim());
RequestBody gender = RequestBody.create(MediaType.parse("multipart/form-data"), Gender);
RequestBody dob = RequestBody.create(MediaType.parse("multipart/form-data"), String.valueOf(epoch));
apiInterface = RetrofitApiUtils.getAPIService();
apiInterface.Updatemyprofile(Constant.AccessToken, userid, role, name, pincode, address, gender, dob, body ).enqueue(new Callback<UpdateUserProf>() {
#Override
public void onResponse(#NonNull Call<UpdateUserProf> call, #NonNull Response<UpdateUserProf> response) {
try {
if (response.isSuccessful()) {
if (response.body() != null && response.body().getStatus().equals(true)) {
Toast.makeText(getActivity(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
UpdateUserProfData updateUserProfData = response.body().getData();
Log.d("Results ==>>...1", new GsonBuilder().setPrettyPrinting().create().toJson(updateUserProfData));
myprofile(Constant.Userid, Constant.Role);
} else {
Toast.makeText(getActivity(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
CallingToastMethod.showToast(getActivity());
}
} catch (Exception e) {
try {
throw new IOException(e.toString());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
#Override
public void onFailure(Call<UpdateUserProf> call, Throwable t) {
Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
Also I have tried this method for image validation:
if (imgprofile.getDrawable() == null){
Toast.makeText(getActivity(), "Please select Image", Toast.LENGTH_SHORT).show();
}
It works when the user enters its details for the first time but not working for updating it.
My interface class method as follows:
// Update My Profile
#Multipart
#POST("updatemyprofile.php")
Call<UpdateUserProf> Updatemyprofile(#Header("Authorization") String authkey,
#Part("id") RequestBody id,
#Part("role") RequestBody role,
#Part("name") RequestBody name,
#Part("pincode") RequestBody pincode,
#Part("address") RequestBody address,
#Part("gender") RequestBody gender,
#Part("dob") RequestBody dob,
#Part MultipartBody.Part image);
Please tell me how to do this I have been stuck on this for days and don't know how to do this...
Thank you! Be safe..
May be your picturePath not found
Try inside if condition:
if(picturePath != null){
File file = new File(picturePath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
}```

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

Set header in retrofit http post request

I have a retrofit interface (kotlin):
interface Api {
#POST("updates")
fun getDetails(#Header("Authorization") token: Token,
#Body body: RequestBody): Single<ResponseObject>
}
When I call it like this (in java),
List<String> apps = Arrays.asList("app1", "app2");
JSONObject jsonObject = new JSONObject();
RequestBody requestBody;
try {
jsonObject.put("apps", new JSONArray(apps));
}
catch(JSONException e) {
e.printStackTrace();
}
requestBody = RequestBody.create(jsonObject.toString(), MediaType.get("application/json"));
api.getDetails(token, requestBody); // works
It works and returns the proper data.
My problem is that I don't want to create a new RequestBody object for each call, so instead of receiving a RequestBody, I want my interface to receive the JSON Object. When I try this however,
interface Api {
#POST("updates")
fun getDetails(#Header("Authorization") token: Token,
#Header("Content-Type") type: String,
#Body body: JSONObject): Single<ResponseObject>
}
api.getDetails(token, "application/json", jsonObject); // does not work
it returns with a retrofit2.adapter.rxjava2.HttpException: HTTP 400 error.
How do I make this http call with just the JSONObject? I think there may be something wrong with how I am specifying the Content-Type, but I can't figure it out.

Send Form data to server in Retrofit

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

Categories