Retrofit 2 - Post FieldMap with Body Object - android

I want to post a HashMap and a Object using Retrofit.
I tried this code below but received IllegalArgumentException.
#POST("update")
Call<RSP010> postApi010(#FieldMap HashMap<String, String> defaultData, #Body User user);
Logcat
java.lang.IllegalArgumentException: #FieldMap parameters can only be used with form encoding. (parameter #1)
But when I add #FormUrlEncoded. It said
java.lang.IllegalArgumentException: #Body parameters cannot be used with form or multi-part encoding. (parameter #2)
UPDATE CODE
public static HashMap<String, String> defaultData(){
HashMap<String, String> map = new HashMap<>();
map.put("last_get_time", String.valueOf(SharedPreferencesHelper.getLongValue(AppConstants.LAST_GET_UPDATE)));
map.put("duid", SharedPreferencesHelper.getStringValue(AppConstants.DUID));
return map;
My Object which I want to post
int profile_id;
private String name;
private String name_kana; // あいうえお
private int gender; // 1 nam 2 nu
private String birth_day;
private String birth_time;
private String birth_place;
private String relationship;
Explain:
I want to post multiple variables via API to server. FieldMap defaultData for default variables I want to use in every API.
https://futurestud.io/tutorials/retrofit-send-objects-in-request-body I've read this, it said instead of posting all separate variables of an object, I can post an object directly.

You can send #Body User user with #FieldMap HashMap<String, String> defaultData like
String user = new Gson().toJson(user);
HashMap<String, String> map = new HashMap<>();
map.put("last_get_time", String.valueOf(SharedPreferencesHelper.getLongValue(AppConstants.LAST_GET_UPDATE)));
map.put("duid", SharedPreferencesHelper.getStringValue(AppConstants.DUID));
map.put("duid", SharedPreferencesHelper.getStringValue(AppConstants.DUID));
map.put("user", user);
OR
Use #PartMap Map<String, RequestBody>
#Multipart
#POST("update")
Call<RSP010> postApi010(#PartMap Map<String, RequestBody> defaultData);
And create your request parameters
Map<String, RequestBody> map = new HashMap<>();
map.put("last_get_time", toRequestBody(String.valueOf(SharedPreferencesHelper.getLongValue(AppConstants.LAST_GET_UPDATE))));
map.put("duid", toRequestBody(SharedPreferencesHelper.getStringValue(AppConstants.DUID)));
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),new Gson().toJson(user));
map.put("user", body);
// This method converts String to RequestBody
public static RequestBody toRequestBody (String value) {
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value);
return body ;
}

Modify your method to:
#POST("update")
Call<RSP010> postApi010(#Query("last_get_time") String lastGetTime,
#Query("duid") String uid,
#Body User user);

Related

Send a key value list object to retrofit

I want to send this
"question_id": 1,
"answer_id": {
"answerId1": "value1",
"answerId2": "value2"
}
through retrofit in android
I sent this
"question_id": 1,
"answer_id": [
1,
2
]
like that
#FormUrlEncoded
#POST(".....")
#Field("question_id") String questionId, #Field("answer_id[]") ArrayList<String> answerId)
how to do the same for the first request? btw HashMap<String,String> is not working
Try this
public interface myService {
#POST("/api/mypath/test")
#FormUrlEncoded
void getPositionByZip(#Query("question_id") String question_id, #FieldMap Map<String, String> answer_id);
}
// Map params need set key and value pair like
// answer_id.put("answerId1","value1");
// answer_id.put("answerId2","value2");
You can use Gson Class and it converts to a string :
List<Answer> answerlist= new ArrayList<>();
Answer model = new Answer();
answerlist.add(model);
Gson gson = new Gson();
String finallocation = gson.toJson(answerlist);
#FormUrlEncoded
#POST("example.com/question")
Observable<Response> sendAnswer(
#Field("question_id") String question_id,
#Field("answer") String answer);

No able to send raw json in retrofit

I have been trying to send raw json using retrofit 2 but not working, i have tried JsonObject , map but it's not working at all. I don't understand what the problem is. Works fine on Postman.
I am trying to send this request:
{
"incomes":[{"amount":"5566","incomeId":"345"}]
}
my android code is:
#Headers({"Accept: application/json"})
#POST("/api/v1/addIncome")
Call<ResponseBody> addIncome(#Body Map<String, String> params);
Map<String, String> params = new HashMap<>();
Call<ResponseBody> req = null;
Income[] incomes = new Income[1];
incomes[0] = income;
params.put(URLParam.INCOMES, new Gson().toJson(incomes));
req = CustomUtil.getCuumiAPIObject(this, URLConstant.BASE_URL).addIncome(params);
I know added the relavent part, rest works fine with other services, problem is of parameter.In response server gives a null value exception meaning, the parameter their is not picking up the value. Would really appreciate some help.
While sending String Map, You need to send it with #FieldMap instead of String Map as #Body.
Use #FiledMap as below in your code:
#FieldMap Map<String, String> params
Edit
If you want to send your json with #Body, you need to send with pojo class as #Body by setting your value in pojo class.
Pojo class:
public class Incomes {
#SerializedName("incomes")
#Expose
private List<Income> incomes = null;
public List<Income> getIncomes() {
return incomes;
}
public void setIncomes(List<Income> incomes) {
this.incomes = incomes;
}
public class Income {
#SerializedName("amount")
#Expose
private String amount;
#SerializedName("incomeId")
#Expose
private String incomeId;
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getIncomeId() {
return incomeId;
}
public void setIncomeId(String incomeId) {
this.incomeId = incomeId;
}
}
}
Then you need to create object of Incomes class and need to set every income in created object of Incomes class.
Incomes incomes=new Incomes();
Incomes.Income mIncome=new Incomes().new Income();
mIncome=income;
incomes.setIncomes(mIncome);
Then send Incomes class object as #Body in you API request.
req = CustomUtil.getCuumiAPIObject(this, URLConstant.BASE_URL).addIncome(incomes);
You also need to change your addIncome method as below:
Call<ResponseBody> addIncome(#Body Incomes incomes);
Hope this helps you.

How to post data using HashMap in retrofit?

Can you please explain how to post data using hashmap in retrofit2 ?
This is what I post
#FormUrlEncoded
#POST("getProfile")
Call<YourResponseObject> getProfile(#FieldMap HashMap<String, String> data);
And the HashMap
HashMap<String, String> map = new HashMap<>();
map.put("token", "yourtoken");
map.put("yourvariable", "yourvariable");
From Retrofit2 documentation check FieldMap for more details
You need to create your interface
public interface YourPostService {
#FormUrlEncoded
#POST("/myEndpoint")
Call<YourResponseClass> postData(#FieldMap Map<String, String> fields);
}
and after this is easy to call and use it

Retrofit2 issue with posting array

I'm developing a client app for android and my API requires me to send picture names in ArrayList<String> like:
collection[0] = 15a877ce9f22bc8349cac80565c4bff6.jpg
collection[1] = 25a877ce9f22bc8349cac80565c4bff6.jpg
but when i send it it goes in the form like:
collection[] = 15a877ce9f22bc8349cac80565c4bff6.jpg
collection[] = 25a877ce9f22bc8349cac80565c4bff6.jpg
my retrofit interface:
#Field("collection[]") ArrayList<String> collection);
how can I achieve the requested result?
any help would be appreciated! Thank you!
Don't put [] in the #Field name, I don't know exactly why you are doing this but it could be confusing as those are reserved character...
You can use something like this:
// ApiService.java
#FormUrlEncoded
#POST("/api/projectLost")
public void projectMarkLost(
#Field("apiKey") String apiKey,
#Field("project_id") int projectId,
#Field("lost_project_remark") String lostProjectRemark,
#Field("lost_project_reasons") ArrayList<Integer> lostProjectReasons,
Callback<JsonObject> cb
);
// Content wish to post
POST content:
apiKey = EzAvFvScs45a2DRI0MktdIDeVRbP59
project_id = 986
remark = testing
details = [detail_1,detail_2]
I found a solution of using Map to achive a desirable result
#FormUrlEncoded
#POST("user/news")
Call<CreateNews> createNews(
#Field("text") String text,
#FieldMap Map<String, String> collection);
and in method:
public void createNews(String text, ArrayList<String> collection, final Callback<CreateNews> callback){
News createNews = ServiceGenerator.createService(News.class);
SortedMap fields = new TreeMap<String, String>();
for (int i = collection.size()-1 ; i >= 0 ; i--) {
fields.put("collection["+i+"]", collection.get(i));
}
Call<CreateNews> call = createNews.createNews(text, fields);
call.enqueue(callback);

Convert Object to map for retrofit GET

I'm start with Retrofit.
I thought of Jackson but has given me problems and I guess there will Retrofit thought about this
I have GET endpoints.
I need convert this:
public class BaseRequest {
private String param1;
private String param2;
private String param3;
//Getter & Setters ...
}
on a Map <String, String>
i'm using dagger + retrofit.
How do I can do this?
Thanks
You'll need to provide more information on this, do the parameters have the same query param name or different.
If they are different you can just pass them in as a #QueryMap Map<String, String> params being a Map of key/value pairs. Such that the output would be something like
Map<String, String> values = new HashMap<>();
values.put("name1", "value1");
values.put("name2", "value2");
values.put("name3", "value3");
?name1=value1&name2=value2&name3=value3
If they are the same then you need #Query("name") String... values), the output of this would be something like:
List<String> values = new ArrayList<>();
values.add("value1");
values.add("value2");
values.add("value3");
?name=value1&name=value2&name=value3

Categories

Resources