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
Related
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);
Retrofit converts POST in GET request when URL is like this
https://www.example.com/index.php?route=api/account/login
Found the solution
#FormUrlEncoded
#POST("index.php")
Call<String> login(#QueryMap(encoded=true) Map<String, String> options,#Field("email") String username,#Field("password") String password);
and calling will be like this
Map<String, String> map = new HashMap<>();
map.put("route","restapi/account/login");
Call<String> call = mAPIService.login(map, email, password);
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);
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 :)
I am writing a client-server Android application. I need to send a file created by user (photo) to server via POST request. The problem is, that when i try to send a file, i can't add a POST Field to my request. Maybe I'm wrong fundamentally, and this operation should be done another way?
#FormUrlEncoded
#Multipart
#POST("/answer/add-file")
Call<AbstractServerResponse> sendSingleFile(#Query("access-token") String accessToken,
#Query("w") String screenWidth,
#Field("answer_id") Integer answerId,
#Part("file") File fileToUpload);
When i try to send files in a multipart way only, i get an exception:
java.lang.IllegalStateException: JSON must start with an array or an object.
As I understand, this happends because the body (main part) of the request is empty.
Multipart requests are used when #Multipart is present on the method. Parts are declared using the #Part annotation.
------ from http://square.github.io/retrofit/
I'm using #Multipart in my project like this:
#POST("/{action}")//POST 多个文件
#Multipart
public void PostAPI(
#Path(value = "action", encode = false) String action,
#Part("path") TypedFile[] typedFiles,
#PartMap Map<String, String> params,
Callback<APIResponse> callback);
Maybe u can try this:
#Multipart
#POST("/answer/add-file")
Call<AbstractServerResponse> sendSingleFile(
#Query("access-token") String accessToken,
#Query("w") String screenWidth,
#Part("answer_id") Integer answerId,
#Part("file") File fileToUpload);
You cannot use both #FormUrlEncoded and #Multipart on a single method. An HTTP request can only have one Content-Type and both of those are content types.