I want to send a post request which contains jsonObject and an image and various other fields and I used MultiPart for image and have successfully uploaded the image but the jsonObject is uploaded in string format
Here is my Api Interface
#Multipart
#POST("operator/upload")
Call<JsonObject>upload(#Header ("Authorization") String t,
#Part MultipartBody.Part img,
#Part("fullName") RequestBody name,
#Part("fatherName") RequestBody fathername,
#Part("aadharNumber") RequestBody aadharnumber,
#Part("dob") RequestBody dob,
#Part("registeredAddress") RequestBody address,
#Part("gender") RequestBody gender,
#Part("plantId") RequestBody plant,
#Part MultipartBody.Part data,
#Part("authorized") Boolean auth,
#Part("verified") Boolean ver) ;
Here is the Retrofit service function
public void userUpload(String p, MultipartBody.Part image, RequestBody name, RequestBody fathername, RequestBody aadharnumber, RequestBody dob, RequestBody address, RequestBody gender, RequestBody plant, MultipartBody.Part cap, Boolean aut, Boolean ver, Response_listner response_listner) {
Call<JsonObject> call = api_interface.upload(p, image, name, fathername, aadharnumber, dob, address, gender, plant,cap,aut,ver);
serveCall(call, response_listner);
}
The ServeCall Method is here
private void serveCall(Call<JsonObject> call, Response_listner responce_listner) {
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
try {
responce_listner.onResponseSuccess(response);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
try {
responce_listner.onResponseFailure(t);
Log.d("Network", t.getMessage());
Log.d("Network Cause", t.getCause().getMessage());
Log.d("NetworkStack", t.getStackTrace().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
And My Main Code where I Made an Api Call
HashMap<String, String> num2 = new HashMap<>();
num2.put("client_id",String.valueOf(CLIENT_ID));
num2.put("full_name",String.valueOf(FULL_NAME));
num2.put("aadhaar_number",String.valueOf(AADHAR_NUMBER));
num2.put("dob",String.valueOf(DOB));
num2.put("gender",String.valueOf(GENDER));
num2.put("face_status",String.valueOf(FACE_STATUS));
num2.put("face_score",String.valueOf(FACE_SCORE));
num2.put("zip",String.valueOf(ZIP));
num2.put("profile_image",String.valueOf(PROFILE_IMAGE));
num2.put("has_image",String.valueOf(HAS_IMAGE));
num2.put("mobile_hash",String.valueOf(MOBILE_HASH));
num2.put("raw_xml",String.valueOf(RAW_XML));
num2.put("zip_data",String.valueOf(ZIP_DATA));
num2.put("care_of",String.valueOf(CARE_OF));
num2.put("share_code",String.valueOf(SHARE_CODE));
num2.put("mobile_verified",String.valueOf(MOBILE_VERIFIED));
num2.put("reference_id",String.valueOf(REFERENCE_ID));
MultipartBody.Part delta = MultipartBody.Part.createFormData("aadharDetails", num2.toString());
RetrofitClient.getInstance_new().userUpload(TokenData, image, name, fathername, aadharnumber, dobb, addresss, genderr, plant,delta, auth, ver, new Response_listner() {
#Override
public void onResponseSuccess(Response baseResponse) throws IOException, JSONException {
if (baseResponse.isSuccessful()) {
Log.e("Response",baseResponse.body().toString());
JSONObject jsonObject = new JSONObject(baseResponse.body().toString());
prog_close();
Intent intent = new Intent(RegisterOP.this, Done.class);
startActivity(intent);
finish();
}
// }
} else {
Toast.makeText(RegisterOP.this, baseResponse.message(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onResponseFailure(Throwable throwable) {
Toast.makeText(RegisterOP.this, throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
});
So the data that I'm sending all is good except delta which is request body somehow it sends string rather than HashMap
Your Help Is Greatly Appreciated !!
Related
My requirement is to pass the request in the below format,
I don't have any idea on how to send request in the below format using a #PartMap,
{
"image", img1.jpg,
"image", img2.jpg,
"service_request", "asd123123asfsf"
}
The type for above format,
{
"<String>", <Image file>,
"<String>", <Image file>,
"<String>", "<String>"
}
My current method
private void uploadMultipleFiles() {
SharedPreferences preferences = getApplicationContext().getSharedPreferences("MY_APP", Context.MODE_PRIVATE);
String retrivedToken = "Token " + preferences.getString("TOKEN", null);
String attachment_one = preferences.getString("Attachement_one", null);
String attachement_two = preferences.getString("Attachement_two", null);
File file_one = new File(attachment_one);
File file_two = new File(attachement_two);
RequestBody requestBody1 = RequestBody.create(MediaType.parse("*/*"), file_one);
RequestBody requestBody2 = RequestBody.create(MediaType.parse("*/*"), file_two);
MultipartBody.Part fileToUpload1 = MultipartBody.Part.createFormData("file1", file_one.getName(), requestBody1);
MultipartBody.Part fileToUpload2 = MultipartBody.Part.createFormData("file2", file_two.getName(), requestBody2);
Call<ResponseBody> call = ServiceBuilder.getInstance().getApi().uploadImages(retrivedToken, "multipart/form-data", fileToUpload1, fileToUpload2, filename);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (!response.isSuccessful()) {
System.out.println("Response Code: " + response.code());
return;
} else {
System.out.println("Response Code: " + response.code());
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
System.out.println("Message: " + t.getMessage());
}
});
}
Service method
#Multipart
#POST("http://192.168.1.100:8000/yrtp/service/request/upload")
Call <ResponseBody> uploadImages(#Header ("Authorization") String token, #Header("Content-Type") String type, #Part MultipartBody.Part file1, #Part MultipartBody.Part file2, #Part("service_request") RequestBody description);
I'm new in using the #PartMap in retrofit and android. Kindly help me with a solution. Million thanks in advance!
I tried to upload a PDF file [Not Image] in PHP API from Android, and I'm getting 400 with this exception:
{"head":{"StatusValue":400,"StatusText":"Failed"},"body":{"Error":"Missing required property fileId"}}
I'm getting 200 request code, when I'm doing in Postman:
Now, Android code:
#Multipart
#POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(#Part MultipartBody.Part file, #Part("fileName") RequestBody name, #Part("body") JSONObject body);
private void uploadPDF(String path) {
String pdfname = String.valueOf(Calendar.getInstance().getTimeInMillis());
File file = new File(path);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("fileName", file.getName(), requestBody);
RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), pdfname);
try {
JSONObject sJsonAttachment = new JSONObject();
JSONObject body = new JSONObject();
sJsonAttachment.put("appointmentId", AdapterCollections.clsClaimDiscussionList.get(position).appointment_id);
sJsonAttachment.put("createdBy", Integer.parseInt(preferenceManager.getUserId()));
sJsonAttachment.put("customerId", Integer.parseInt(preferenceManager.getCustomerId()));
sJsonAttachment.put("encounterId", AdapterCollections.clsClaimDiscussionList.get(position).encounter_id);
sJsonAttachment.put("expiryDate", Utility.getCurrentDate("MM-DD-YY"));
sJsonAttachment.put("fbType", 4);
sJsonAttachment.put("fileId", 0);
sJsonAttachment.put("fileName", "name");
sJsonAttachment.put("insTpaPatId", 0);
sJsonAttachment.put("isActive", 1);
sJsonAttachment.put("messageId", AdapterCollections.clsClaimDiscussionList.get(position).log_messages.get(position).log_id);
sJsonAttachment.put("patientId", AdapterCollections.clsClaimDiscussionList.get(position).patient_id);
sJsonAttachment.put("recType", "");
sJsonAttachment.put("reportDate", Utility.getCurrentDate("DD-MM-YYYY"));
sJsonAttachment.put("siteId", Integer.parseInt(preferenceManager.getSiteId()));
sJsonAttachment.put("type", 4);
sJsonAttachment.put("uploadDate", Utility.getCurrentDate("MMDDYY"));
// body.put("body", sJsonAttachment);
ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
assert apiCall != null;
apiCall.uploadFile(fileToUpload, filename, sJsonAttachment).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NotNull Call<ResponseBody> call, #NotNull Response<ResponseBody> response) {
try {
showLog("STATUS: " + response.code());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(#NotNull Call<ResponseBody> call, #NotNull Throwable t) {
showLog("FAILED: "+ t.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
I know that I'm doing somewhere small mistakes, but not able to spot that.
If I used part then this error: Missing required property fileId, and if I use query then this error: must be object.
Update
Regarding Path:
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="/storage/emulated/0" path="."/>
</paths>
Intent to open PDF chooser:
private void fileDialog() {
Intent intent = new Intent().setType("application/pdf").setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "Select PDF file"), 123);
}
I followed this https://stackoverflow.com/a/62830720/12630878 answer to getPath, but, I'm NOT getting path properly.
Higher version means: 28 to 30
Higher Version URI:
URI: content://com.android.providers.media.documents/document/document%3A31
FROM RECENT, If I'll choose PDF, then cursor is returning null:
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
FROM DOWNLOADS, if I'll choose PDF, then NumberFormatException coming on this line:
URI: content://com.android.providers.downloads.documents/document/msf%3A27
Exception: java.lang.NumberFormatException: For input string: "msf:27"
LINE NO: Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
FileUtils class: https://drive.google.com/file/d/1S5-Sdp_CCSXXsOsZxwuhv0F5_CtH2EQO/view?usp=sharing
Search this method where I'm getting Path:
public static File getFile(Context context, Uri uri) {
if (uri != null) {
String path = getPathForAllVersion(context, uri);
// String path = getFilePathFromURI(context, uri);
showLog("isPATH: " + path);
if (checkNull(path) && isLocal(path)) {
return new File(path);
}
}
return null;
}
You api accept only two parameters but you passed three parameters that's why you getting error.
so API method should be
#Multipart
#POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(
#Part("body") RequestBody description,
#Part MultipartBody.Part file
);
And update your uploadPDF() like below
private void uploadPDF(String path) {
//json data
JSONObject sJsonAttachment = new JSONObject();
JSONObject body = new JSONObject();
sJsonAttachment.put("appointmentId", AdapterCollections.clsClaimDiscussionList.get(position).appointment_id);
sJsonAttachment.put("createdBy", Integer.parseInt(preferenceManager.getUserId()));
sJsonAttachment.put("customerId", Integer.parseInt(preferenceManager.getCustomerId()));
sJsonAttachment.put("encounterId", AdapterCollections.clsClaimDiscussionList.get(position).encounter_id);
sJsonAttachment.put("expiryDate", Utility.getCurrentDate("MM-DD-YY"));
sJsonAttachment.put("fbType", 4);
sJsonAttachment.put("fileId", 0);
sJsonAttachment.put("fileName", "name");
sJsonAttachment.put("insTpaPatId", 0);
sJsonAttachment.put("isActive", 1);
sJsonAttachment.put("messageId", AdapterCollections.clsClaimDiscussionList.get(position).log_messages.get(position).log_id);
sJsonAttachment.put("patientId", AdapterCollections.clsClaimDiscussionList.get(position).patient_id);
sJsonAttachment.put("recType", "");
sJsonAttachment.put("reportDate", Utility.getCurrentDate("DD-MM-YYYY"));
sJsonAttachment.put("siteId", Integer.parseInt(preferenceManager.getSiteId()));
sJsonAttachment.put("type", 4);
sJsonAttachment.put("uploadDate", Utility.getCurrentDate("MMDDYY"));
// create RequestBody instance from file
File file=new File(path);
RequestBody requestFile =
RequestBody.create(
MediaType.parse(Files.probeContentType(file.toPath()))),
file
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part fileBody =
MultipartBody.Part.createFormData("fileName", file.getName(), requestFile);
// add another part within the multipart request
RequestBody bodyJsonAttachment =
RequestBody.create(
okhttp3.MultipartBody.FORM, sJsonAttachment.toString());
ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
assert apiCall != null;
apiCall.uploadFile(fileBody, bodyJsonAttachment).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NotNull Call<ResponseBody> call, #NotNull Response<ResponseBody> response) {
try {
showLog("STATUS: " + response.code());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(#NotNull Call<ResponseBody> call, #NotNull Throwable t) {
showLog("FAILED: "+ t.getMessage());
}
});
}
Note : if you getting warning error on mime type, update it
If you are using multipart then pass all the field in Multipart just like this.
Declare method in Api interface just like this. Only one MultipartBody field.
#Multipart
#POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(#Body MultipartBody body);
Create MultipartBody.Builder add your and your field in it.
MultipartBody.Builder requestBodyBuilde = MultipartBody.Builder().setType(MultipartBody.FORM);
//adding image in multipart
File file = File(selected_file_path);
RequestBody fileBody = ProgressRequestBody(file, this);
requestBodyBuilde.addFormDataPart("fileName", file.name, fileBody);
//add your other field just like this
requestBodyBuilde.addFormDataPart("body", sJsonAttachment );
ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
assert apiCall != null;
//Note here we will pass only one parameter that is multipartBody
apiCall.uploadFile(requestBodyBuilde.build()).enqueue(new
Callback<ResponseBody>() {
#Override
public void onResponse(#NotNull Call<ResponseBody> call, #NotNull Response<ResponseBody> response) {
try {
showLog("STATUS: " + response.code());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(#NotNull Call<ResponseBody> call, #NotNull Throwable t) {
showLog("FAILED: "+ t.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
i am facing a problem regarding posting data in an array in android using retrofit 2. i have to post the data of nearly 14 fields in my profile setting activity ...
Like this ...
name="basics[first_name] , name="basics[last_name]" , name="basics[phone_number]"
i have to send data in this format. i am not understanding how to do it need help.i am not understanding how to make Call of the api in the interface because i have to put data in an array.
Currently i am doing it like this but i know its not right...
#FormUrlEncoded
#POST("profile_setting/basic_setting")
Call<ResponseBody> UpdateBasics(
#Query("user_id") int user_id ,
#Field("nickname") String nickname ,
#Field("first_name") String first_name ,
#Field("last_name") String last_name ,
#Field("phone_number") String phone_number ,
#Field("fax") String fax
);
Make a class
public class Basic {
public final int user_id;
public final String nickname;
....
public Basic(int user_id, ...) {
}
}
Then pass list of objects of this class to this interface
public interface MyService {
#POST("/basic")
Response void sendData(#Body List<Basic> basic);
}
Or you can do the same with JSONObject. Just make a list of jsonobjects
JSONObject paramObject = new JSONObject();
paramObject.put(value_one, "field_one"));
paramObject.put(value_second, "field_second"));
put the objects in a list
list.add(paramObject);
then pass to the retrofit
public interface MyService {
#POST("/basic")
Response void sendJsonObjectData(#Body List<JSONObject> basic);
}
Do this way to send Json Object as request parameters using Retrofit 2
#Headers("Content-Type: application/json")
#POST("profile_setting/basic_setting")
Call<ResponseBody> UpdateBasics(#Body String body);
This is how you would use the above method to send json object
try {
JSONObject paramObject = new JSONObject();
paramObject.put(value_one, "field_one"));
paramObject.put(value_second, "field_second"));
Call<ResponseBody> userCall = apiInterface.UpdateBasics(paramObject.toString());
userCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//handle your result here
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
//handle failure
}
});
} catch (JSONException e) {
e.printStackTrace();
}
You can follow this was. (posting how i've done that)
#POST("Users.json")
Call<UploadData> uploadToken(#Body UploadData uploadData);
UploadData.class
public class UploadData {
private String DeviceToken, DeviceIMEI;
public UploadData(String deviceToken, String deviceIMEI) {
DeviceToken = deviceToken;
DeviceIMEI = deviceIMEI;
}
public String getDeviceToken() {
return DeviceToken;
}
public String getDeviceIMEI() {
return DeviceIMEI;
}
}
Then in your Activity
private void uploadToken() {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
UploadData uploadToken = new UploadData(deviceToken, imei);
final Call<UploadData> callUpload = apiInterface.uploadToken(uploadToken);
callUpload.enqueue(new Callback<UploadData>() {
#Override
public void onResponse(Call<UploadData> call, Response<UploadData> response) {
if (response.isSuccessful()) {
Toasty.success(Main.this, "Token Uploaded !! ", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure (Call < UploadData > call, Throwable t){
call.cancel();
Toasty.error(Main.this, "Error: " + t.getLocalizedMessage(),Toast.LENGTH_SHORT).show();
}
});
}
My image is not getting upload to server i have searched several links but didn't find the useful way bellow are the codes
RFInterface.java
#Multipart
#POST("compose_notice")
Call<PostNoticeModel> compose_notice(
#Query("apartment_id") String apartment_id,
#Query("subject") String subject,
#Query("descriptions") String descriptions,
#Query("expiry_time") String expiry_time,
#Query("notice_visible_group") String notice_visible_group,
#Query("selectedUser") String selectedUser,
//#Part ("attachmentFile") RequestBody file
//#Part ("attachmentFile\"; filename=\"attachmentFile\" ") RequestBody attachmentFile
#Part MultipartBody.Part attachmentFile
);
here are the code from where i am getting response to rfinterface.java file
btn_submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
get_title = edt_title.getText().toString();
get_description = edt_description.getText().toString();
if(get_expires.equals("Custom")){
get_expires = custom_date.getText().toString();
}
if(get_title.trim().length() == 0){
Toast.makeText(PostNotice.this, "Please enter title", Toast.LENGTH_SHORT).show();
}else if(get_description.trim().length() == 0){
Toast.makeText(PostNotice.this, "Please enter description", Toast.LENGTH_SHORT).show();
}else {
if(finalfile != null) {
reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), finalfile);
body = MultipartBody.Part.createFormData("attachmentFile", finalfile.getName(), reqFile);
// get_titlee =
// RequestBody.create(MediaType.parse("multipart/form-data"), get_title);
}else{
body = null;
}
//Toast.makeText(PostNotice.this, ""+body, Toast.LENGTH_SHORT).show();
RFInterface api = RFClient.getApiService();
Call<PostNoticeModel> call = api.compose_notice(apartment_id, get_title, get_description, get_expires, get_noticevisibility, suserstring, body);
final ProgressDialog progressDoalog;
progressDoalog = new ProgressDialog(PostNotice.this);
progressDoalog.setMessage("Its loading....");
progressDoalog.setTitle("Please wait it take some time ");
// show it
progressDoalog.show();
call.enqueue(new Callback<PostNoticeModel>() {
#Override
public void onResponse(Call<PostNoticeModel> call, Response<PostNoticeModel> response) {
if (response.isSuccessful()) {
getresponse = response.body().getMsg();
Toast.makeText(getApplicationContext(), getresponse, Toast.LENGTH_LONG).show();
progressDoalog.dismiss();
} else {
Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
progressDoalog.dismiss();
}
}
#Override
public void onFailure(Call<PostNoticeModel> call, Throwable t) {
progressDoalog.dismiss();
}
});
}
}
});
please tell me where i am doing wrong all things are working properly all the data get inserted in table to compose notice but image is not uploaded image column remain empty.
Use Requesbody
#Multipart
#POST(urlString)
fun addField(#PartMap partMap: Map,
#Part imagefile: MultipartBody.Part?
): Observable
I want to creat xml-rpc POST request, and pass 2 parameters "application_name" & "key", and change content type to "application/x-www-form-urlencoded" like my code below.
try {
XMLRPCClient oneTimeKeyClient = new XMLRPCClient(new URL(URL_REQUEST_SAMPLE), XMLRPCClient.FLAGS_DEFAULT_TYPE_STRING);
oneTimeKeyClient.setCustomHttpHeader("X-HTTP-METHOD-OVERRIDE", "POST");
// oneTimeKeyClient.setCustomHttpHeader("Content-Type", "application/x-www-form-urlencoded");
HashMap<String, String> oneTimeKeyParam = new HashMap<>();
oneTimeKeyParam.put("application_name", "hello_app");
oneTimeKeyParam.put("key", "bb5eb953d3b41dcf59f4669d98f8e14782ed83133be772956b");
Vector<Object> params = new Vector<Object>();
params.add(oneTimeKeyParam);
oneTimeKeyClient.callAsync(new XMLRPCCallback() {
#Override
public void onResponse(long id, Object response) {
try {
result = ((Map) response).get(NAME_ONE_TIME_KEY).toString();
} catch (Exception e) {
Timber.e("onParseError %s", e.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
}
#Override
public void onError(long id, XMLRPCException error) {
Timber.e("onError %s", error.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
#Override
public void onServerError(long id, XMLRPCServerException error) {
Timber.e("onServerError %s", error.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
}, "", params);
} catch (Exception e) {
Timber.e("onError %s", e.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
I got error " onServerError APPLICATION_NAME must record not exists."
I using aXMLRPC library https://github.com/gturri/aXMLRPC .
Which library do you recommend ?
Can I use Retrofit to make xml-rpc request ?
Thanks for any help
You just use retrofit like this:
#FormUrlEncoded
#POST("onetime_key")
Observable<OneTimeKeyRes> requestOneTimeKey(#Field("application_name") String applicationName, #Field("key") String key);
You must add SimpleXmlConverter:
Retrofit retrofit = new Retrofit.Builder()
.client(builder.build())
.baseUrl(YOUR_BASE_URL)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();