Android Retrofit 2 make POST request multiple params (without FormUrlEncoded) - android

I would like to make a POST request call with multiple params instead of one #Body param. I'm not using #FormUrlEncoded annotation on this one and I don't want to. I'm using Retrofit 2.0.
Currently, the call is made this way :
#POST("user/register")
Call<APIResponse> register(#Body RequestRegisterParams params);
with RequestRegisterParams being :
public class RequestRegisterParams {
public String username;
public String email;
public String password;
}
I would like to be able to do this (with proper annotations of course) :
#POST("user/register")
Call<APIResponse> register(String username, String email, String password);
My goal is to get rid of the data model class. Is there a way to do this or a POST request without #FormUrlEncoded must have only one #Body param ? I know it can only be one #Body param but maybe with other annotations ?
Thanks in advance !

#FormUrlEncoded
#POST("user/register")
Call<APIResponse> updateUser(#Field("username") String username, #Field("email") String email, #Field("password") String password);
#Field is Named pair for a form-encoded request.

Related

Retrofit best practice for PATCHing single fields

What is the most common and appropriate way to update single fields of a JSON resource with a PATCH request in Retrofit?
I see 3 ways of doing it:
Using #Body to send the full object, while leaving fields that are not supposed to be updated as null, so GSON will drop them:
#PATCH("posts/{id}")
Call<Post> patchPost(#Path("id") int id, #Body Post post);
Using #FormUrlEncoded and only pass the fields that are supposed to be updated, for example with a #FieldMap.
#FormUrlEncoded
#PATCH("posts/{id}")
Call<Post> patchPost(#Path("id") int id, #FieldMap Map<String, String> fields);
Defining a custom model class that only contains fields that are supposed to be updated, so we don't have to set anything to null.
#PATCH("posts/{id}")
Call<Post> patchPost(#Path("id") int id, #Body PostUpdate postUpdate);
Am I missing other ways? Which one is the most commonly used?
I generally use JSON with RequestBody(Okhttp). JSON object includes just relevant fields. And then I convert it RequestBody. It's like below:
#PATCH(RestConstants.POST_EMPTY)
Call<EmptyResponseModel> postEmpty(#Body RequestBody body);
MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json.toString()));

Multiple Post request with different parameter Retrofit

I have something like this in the interface
#POST("login")
Call<LoginResponse> Login(#Query("email") String email,
#Query("password") String password);
I want to make the first parameter's name to become either email or user_name according to whether typed in the editText is email or username
How I can achieve this
You can use #QueryMap for this purpose
#POST("login")
Call<LoginResponse> Login(#QueryMap Map<String, String> options);
And use it like this
Map<String, String> data = new HashMap<>();
data.put("email", "mail#example.com"); //change email to user_name when you need
data.put("password", "secret");
...
...
loginService.Login(data);
Why not create a separate service/function if they enter a user_name? I.e.
#POST("login")
Call<LoginResponse> LoginByUsername(#Query("user_name") String userName,
#Query("password") String password);

Change user-type in API Header or change header using variable

I declare a final variable in global
public static final String USERTYPE="customer"
Then I use this variable as
#POST
#Headers({
"Content-Type: application/json;charset=utf-8",
"Accept: application/json;charset=utf-8",
"Cache-Control: max-age=640000",
"user-type: " + APIService.STRING
})
Call<ReturnPojo> addpost(#Url String s, #Body Add body);
Later in my program, I need to change the
USERTYPE="guest"
I try
1.USERTYPE.replace("customer","guest");
2.String user="customer"
USERTYPE=user;
How can I achieve this? or How to change a final variable in java?
You can't. You've declared USERTYPE as final so the only choice you have is to use a different String.
Change Header on Run-time(Retrofit API)
We cannot change the final variable, So we cannot change the user type programmatically. By duplicating the code is not good practice. But we can be done through this,
#POST
Call<ReturnPojo> addpost(#Url String s,
#Body Add body,
#Header("user-type") String user_type,
#Header("Content-Type") String content_type,
#Header("Accept") String accept,
#Header("Cache-Control") String cache_controller);
And finally, while we call API just pass the data as the parameter.

Retrofit encodes Body

I have an API call to make. I am using Retrofit to make the call like below:
#POST("/speak?api-version=2.0")
Observable<Response> testAPICall(
#Header("Content-Type") String contentType,
#Body String text,
#Query("language") String languageCode,
);
I am calling the API like:
String bodyString = "<markerbegin>blah<markerend/>";
testAPICall("application/ssml+xml", bodyString,"en-US");
Problem is that, the bodyString gets encoded. So, the '<' or '>' or '/' etc. getting encoded as /u003 etc.
Searching SO didn't help. I tried - using FormUrlEncoding, which didn't compile and also passing the body as bytes[] but that failed as well.
Any help will be appreciated.
I changed the signature from String to TypedString:
from #Body String text --> #Body TypedString text,
Observable<Response> testAPICall(
#Header("Content-Type") String contentType,
#Body TypedString text,
#Query("language") String languageCode,
);
Instead of passing a String, I passed: new TypedString(theText)

Sending various parameters (JSON) using Retrofit 2

This is the interface method:
#FormUrlEncoded
#POST (“url/myurl")
Call<JsonArray> sendParameters (#Header("x-imei") String imei, #Header("x-id-cliente") String idCliente, #Field(“param1") JsonObject param1, #Field(“param2") JsonArray param2, #Field(“param3") JsonArray param3, #Field(“param4") JsonArray param4,#Field(“param5") JsonArray param5);
And the method to use it:
Call<JsonArray> peticion= RetrofitClient.getRetrofitClient(getActivity()).sendParameters(settings.getString("imei", ""), settings.getString("idCliente", "”),param1,param2,param3,param4,param5);
This way, the call is not working.
I tried changing all the interface parameters to String, and doing param1.toString(), param2.toString() and so on in the call, and is not working neither.
Is there a simple way to send JsonObjects and JsonArrays in a POST, using Retrofit 2?
Thank you.
First you can create a custom class which you want to pass as a POST body
class CustomClass {
String param1;
String parma2;
String param3;
//all of your params with getters and setters
}
Then you change the Retrofit method according to your new CustomClass instance with the #Body annotation:
#POST (“url/myurl")
Call<JsonArray> sendParameters (#Header("x-imei") String imei, #Header("x-id-cliente") String idCliente, #Body CustomClass customClassInstance);
And eventually you make the call to post data:
CustomClass customClassInstance = new CustomClass();
customClassInstance.setParam1(...);
//...and so on
Call<JsonArray> peticion= RetrofitClient.getRetrofitClient(getActivity()).sendParameters(settings.getString("imei", ""), settings.getString("idCliente", ""), customClassInstance);
EDIT: removed the #FormUrlEncoded annotation

Categories

Resources