Here I m using #Fields data with #FormUrlEncoded But I have to use both in same API #Part("user_image") RequestBody file with #Multipart. How does it possible? Thanks in advance.
#FormUrlEncoded
#POST("/datingapp/index.php/Webservice")
Call<Result> signupUser(#Field("user_name") String name,
#Field("age") String age,
#Field("work") String work,
#Field("home_town") String home_town,
#Field("gender") String gender,
#Field("interest") String interest,
#Field("study") String study,
#Field("email") String email,
#Field("password") String password,
#Field("device_id") String device_id,
#Field("device_type") String device_type,
#Part("user_image") RequestBody file,
#Field("signup") String signup);
Http protocol not allow 2 Content-Type in the same request. So you have to choose :
application/x-www-form-urlencoded
multipart/form-data
You use application/x-www-form-urlencoded by using annotation #FormUrlEncoded in order to send image you have to transform the whole file into text (e.g. base64).
A better approach would be use multipart/form-data by describing your request like that :
#Multipart
#POST("/datingapp/index.php/Webservice")
Call<Result> signupUser(#Part("user_name") String name,
#Part("age") String age,
#Part("work") String work,
#Part("home_town") String home_town,
#Part("gender") String gender,
#Part("interest") String interest,
#Part("study") String study,
#Part("email") String email,
#Part("password") String password,
#Part("device_id") String device_id,
#Part("device_type") String device_type,
#Part("user_image") RequestBody file,
#Part("signup") String signup);
#Multipart
#POST("/datingapp/index.php/Webservice")
Call<Result> signupUser(#PartMap Map<String,String> queryMap,
#Part("user_image") RequestBody file);
Here the #PartMap contains the required other parameters which is nothing but a HashMap containing key and values e.g,
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
map.put("user_name",username);
like above and so on.
Make api call like this :
#POST("/datingapp/index.php/Webservice")
#FormUrlEncoded
#Multipart
Call<Result> signupUser(#FieldMap LinkedHashMap<String, String> data,#Part RequestBody file);
and pass your data is the form of key and value in LinkedHashMap like this
LinkedHashMap<String, String> data = new LinkedHashMap<>();
data.put("user_name", user_name);
data.put("age", age);
data.put("work", work);
data.put("work", work);
data.put("gender", gender); and so on ....
for getting image in Multiparts :
RequestBody file= RequestBody.create(MediaType.parse("image/jpeg"), file);
final call to hit the api :
Call<Result> call = apiService.signupUser(data ,file);
Hope this works :)
Related
I'm sending a multipart request to server and this is my interface:
#Multipart
#POST("v1/group/new")
Call<MyResponse> newGroup(
#Header("token") String token,
#Part MultipartBody.Part photo,
#Part("title") RequestBody subject,
#Part("members") List<RequestBody> members);
and for sending my members in my fragment, I change my List<String> to List<RequestBody> as below:
List<RequestBody> members = new ArrayList<>();
for(int i = 0;i < membersId.size(); i++){
members.add(RequestBody.create(MediaType.parse("text/plain"),membersId.get(i)));
}
and it's working with multiple members! but when there is a one string in my list, retrofit doesn't sends my members as a list!!! for example:
I want to send array of strings like this :
["item1","item2","item3"]
my code works for this, but when there is only one item, retrofit sends this :
"item1"
instead of ["item1"]
what is the proper way of sending array of string in multipart with retrofit?
what am I doing wrong?
Use something like this.
#Multipart
#POST("v1/group/new")
Call<MyResponse> newGroup(
#Header("token") String token,
#Part MultipartBody.Part photo,
#Part("title") RequestBody subject,
#Part("members[]") List<RequestBody> members);
Remember you must add [] to your members param :).
#Multipart
#POST("v1/group/new")
Call<MyResponse> newGroup(
#Header("token") String token,
#Part MultipartBody.Part photo,
#Part("title") RequestBody subject,
#Part("members[]") ArrayList<RequestBody> members);
Two changes:
Change list to ArrayList as ArrayList is Serializable whereas List is not.
add "[]" at the end of the ArrayList type parameter.
I'm trying to make a PUTrequest using retrofit. All parameters sent except the data inside the Classic Java object. it contains a and other data but the backend not adding any of its parameters. I tried adding the HashMap as an individual part "working_session_pauses_attributes" but also not sent. Any solution or suggestion?
Thanks in advance
#Multipart
#PUT(WORKING_SESSION_PATH)
Observable<Response<WorkingSession>> updateWorkingSession(#Path(LOCATION_ID_VARIABLE) String locationId,
#Path(EMPLOYEE_ID_VARIABLE) String employeeId,
#Path(WORKING_SESSION_ID_VARIABLE) String workingSessionId,
#Part("working_session_id") String working_session_id,
#Part("ends_at") String ends_at,
#Part("starts_at") String starts_at,
#Part("secure_id") String secure_id,
#Part ("tag_ids[]") Long[] tag_ids,
#Part ("working_session_pauses_attributes") HashMap<Integer, UpdateBreakDataModel> working_session_pauses_attributes,
#Part ("data") CreateWorkingSessionRequestBody CreateWorkingSessionRequestBody,
#Part MultipartBody.Part end_signature,
#Part MultipartBody.Part start_signature_break,
#Part MultipartBody.Part end_signature_break);
I don't know what are you doing, you want post request but you are using put, please check. I am showing you my code how i am sending data using Hash map.
This is my method declaration:
#GET(ApiConstant.REQUEST_FORM_CHECK_OUT_ID)
Call<CheckOutIdResponseParent> callRequestFormCheckoutId(#QueryMap Map<String, String> params);
& here i am calling that method using hashmap.
Map<String, String> params = new HashMap<>();
params.put("category_id", categoryId);
params.put("currency", currency);
params.put("language", language);
ServiceApi mRetrofitCommonService = RetrofitClient.getInstance();
Call<ProductListParentResponse> call = mRetrofitCommonService.callProductListApi(params);
Following API I called for Editing User Profile . I have to send user profile picture so I used multipart in API .
#Multipart
#POST(ApiURLs.EDIT_USER_PROFILE)
Call<EditProfileModel> EditUserProfile (#Part("user_id) String userId ,
#Part("user_name") String userName ,
#Part("language_id") String languageId ,
#Part("state_id") String stateId ,
#Part MultipartBody.Part
profilePicture);
When Service called the requested parameters would be like
"user_id" : ""23""
"user_name" : ""Keval Shukla""
"language_id": ""27""
"state_id" : "53""
how do i remove that double quote using MultiPart ?
It must be like -
#Multipart
#POST(ApiURLs.EDIT_USER_PROFILE)
Call<EditProfileModel> EditUserProfile (
#Part("user_id") RequestBody userId ,
#Part("user_name") RequestBody userName ,
#Part("language_id") RequestBody languageId ,
#Part("state_id") RequestBody stateId ,
#Part RequestBody profilePicture);
And, to create requestBody,
File file = new File(imageURI.getPath());
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file); // File requestBody
RequestBody userName = RequestBody.create(MediaType.parse("text/plain"), userNameSTRING); // String requestBody
You can send parameters other than file as RequestBody.
#Multipart
#POST(ApiURLs.EDIT_USER_PROFILE)
Call<EditProfileModel> EditUserProfile (#Part("user_id) RequestBody userId ,
#Part("user_name") RequestBody userName ,
#Part("language_id") RequestBody languageId ,
#Part("state_id") RequestBody stateId ,
#Part MultipartBody.Part profilePicture);
To Convert String to RequestBody:
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), userName); // Here userName is String
You are doing it wrong way, when you are using MultiPart as body type you have to specify body type of each request parameter.
For example, you are sending file(image,video etc.) and string parameters. So you need to specify all the parameters and convert it to specific body type.
You need to divide parameters into two parts,
1) MultipartBody - For media file
2) RequestBody - For other string or other data type parameters
e.g.
/*Create API Method*/
#Multipart
#POST("apiurl")
Call<Object> callMethodName(#Part("mobile_no") RequestBody mobile_no, /*String param */
#Part("password") RequestBody password, /*String param */
#Part MultipartBody.Part profile_img /*file param */);
I have define Parse type as multipart/form-data, you can define as according to your requirements,
public static final String MULTIPART_TYPE = "multipart/form-data";
Now create request parameters as below,
/* Adding String Params*/
RequestBody reqNumber = RequestBody.create(MediaType.parse(Constants.MULTIPART_TYPE), number.toString());
RequestBody reqPass = RequestBody.create(MediaType.parse(Constants.MULTIPART_TYPE), pass.toString());
/* Adding File*/
File file = new File(selectedImagePath);
RequestBody requestFile = RequestBody.create(MediaType.parse(Constants.MULTIPART_TYPE), file);
bodyFile = MultipartBody.Part.createFormData("profile_img", file.getName(), requestFile);
As last step, you need to pass request parameter to API call method as below, so it can identify parameters and send it to server.
/* Call API Method */
RestClient.getApiClient().callMethodName(reqNumber, reqPass, bodyFile);
Use RequestBody instead of String.
#Part("user_id") RequestBody user_id,
To call it
String userId= "123456";
RequestBody id =
RequestBody.create(
okhttp3.MultipartBody.FORM, userId);
I have an endpoint where I PUT some data, where the Content-Type should be form-data.
I'm using
#FormUrlEncoded
#PUT("/api/v1/clients/profile/all_details")
Call<ResponseBody> postUserProfile(#FieldMap Map<String, String> userParams);
but while sending the request, the form-data is encoded like
food_allergy=%5Beggs%2C%20milk%2C%20nuts%2C%20none%5D&diet_prefer=Non%20Vegetarian&age=25&exercise_level=Moderate&email=Email&name=Veeresh&height=175&prompt-qgreet3=I%27m%20ready%21&gender=Female&health_condition=%5Bdiabetes%2C%20PCOD%5D&weight=69
How do I remove the encoding?
I tried this blog
https://futurestud.io/tutorials/retrofit-send-data-form-urlencoded-using-fieldmap
You can first of all replace all the % by using
string.replace("%","");
And do the rest the same way.
If you don't want to encode the form data then you can try like this
#PUT("/api/v1/clients/profile/all_details")
Call<ResponseBody> postUserProfile(#QueryMap Map<String, String> userParams);
EDIT 1
#Multipart
#PUT("/api/v1/clients/profile/all_details")
Call<ResponseBody> postUserProfile(#Part(username) RequestBody username, #Part(password) RequestBody password);
And here is how to get requestBody from String.
String username = "username";
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), username);
String password = "password";
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), password);
#FieldMap has an element called encoded which is false by default.
If you set it to true, you're saying my data is already encoded and I don't want Retrofit to handle the encoding.
#FieldMap(encoded = true) Map<String, String> userParams
#FormUrlEncoded
#POST("/api/post")
Call<Response> createPost(
#Header("auth") String auth,
#Field("id") String id,
#Field("title") String title,
#Body ContentData content);
By using this code am getting error saying "#Body parameters cannot be used with form or multi-part encoding.". What should i do now ? I tried to send Object as String that also failed.
If you are sending form-data use Field for your parameters:
#Header("auth: YOUR_AUTH")
#FormUrlEncoded
#POST("/api/post")
Call<Response> createPost(
#Field("id") String id,
#Field("title") String title
);
else if you are using other than form-data like application/json Send your body by #Body:
#Header("auth: YOUR_AUTH")
#POST("/api/post")
Call<Response> createPost(#Body ContentData content);
This all depends upon your requirements.