I need to send this request to my API
?name=yourname&address=youraddress&phone=1245689&email=me#mail.com&gender=M&birth_date=01011998&birth_place=Surabaya&job=myjob .. other 7 string parameters .. &skills[]=skill1&skills[]=skill2
I could do it like this How to post array in retrofit android
But, is there a simple way to do it in retrofit using #Body rather than #Field/#FieldMap?
I have resolved this by following this answer, but if you are to lazy and has made tons of code and don't want to rewrite them, just use List<Object> myObject = new ArrayList<Object>(); (using my own code as example) :
class UserFormRequest {
private String name;
private String address;
...
private List<SkillObject> skills = new ArrayList<SkillObject>(); // this
}
Related
I am using the Retrofit (2.3.0) and I use the Retrofit-GSON-converter to create a POJO.
Let's say I have the following class:
public class Flight {
#SerializedName("fromCity")
private String fromCity;
#SerializedName("toCity")
private String toCity;
#SerializedName("fromAirportName")
private String fromAirportName;
#SerializedName("toAirportName")
private String toAirportName;
// Getters + Setters
}
Now when I use a retrofit call to fetch the model, it parses without error and I get a List with all values set but sometimes I get an empty string for fromCity and toCity from my server.
What I want is to set the value of fromCity and toCity to custom values once the object is constructed such that I do not iterate over the List of the objects and update them individually.
I am starting to use Gson to parse json data.
Jason content will be like
{
“type”: “type1”,
“date”: “Tue, 16 May 2017 07:09:33 +0000”,
“body”:
{
“formatA_1”: “aaa”,
“formatA_2”: “bbbcccddd”
}
}
or
{
“type”: “type_2”,
“date”: “Tue, 16 May 2017 07:09:33 +0000”,
“body”:
{
“formatB_1”: “alpha”
}
}
There will be different kind of types currently to 8 different types. The major different is the "body" part.
The "body" part can have different format and different content even the arraylist or null is possible.
So i design the data class be
public class Data {
private String type;
private Long date;
private String body;
public String getType() {
return type;
}
public long getDate() {
return date;
}
public String getBody() {
return body;
}
}
First i thought that depends on the type, later i can parse the body string, but got the exception:
com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 10 path $.body
Is this the only way that i modify the Data class with nested body class?
public class Data {
private String type;
private Long date;
private Body body;
private class Body {
private String formatA_1;
private String formatA_2;
private String formatB_1;
//even for the list and other data members...
}
}
This design is a bit mess because it contains all the members of the different "type" (type1 , type2, type3, ...).
I want to be that based on different "type", i can parse body to different object (POJO for body). Is that possible?
I am just start to study for using Gson and don't know how to make a better design and parse.
Thanks a lot.
In Question you asking to avoid nested objects , there is only two ways to deal with this and that is to parse data manually , or use #Expose tag in POJO otherwise you have to create a complete POJO as it is.
By Though way i recommend using http://www.jsonschema2pojo.org/ for auto parsing of GSON POJO's from json.
For Detailed parsing examples and there is a good read at http://www.javadoc.io/doc/com.google.code.gson/gson/2.8.2
Also, you can define your class Body as a generic class.
private String type;
private Long date;
private List<T> body;
you have to read more about how to parse a generic class.
I need to send a list / an array of Integer values with Retrofit to the server (via POST)
I do it this way:
#FormUrlEncoded
#POST("/profile/searchProfile")
Call<ResponseBody> postSearchProfile(
#Field("age") List<Integer> age
};
and send it like this:
ArrayList<Integer> ages = new ArrayList<>();
ages.add(20);
ages.add(30);
ISearchProfilePost iSearchProfile = gsonServerAPIRetrofit.create(ISearchProfilePost.class);
Call<ResponseBody> call = iSearchProfile.postSearchProfile(
ages
);
The problem is, the values reach the server not comma separated. So the values there are like age: 2030 instead of age: 20, 30.
I was reading (e.g. here https://stackoverflow.com/a/37254442/1565635) that some had success by writing the parameter with [] like an array but that leads only to parameters called age[] : 2030.
I also tried using Arrays as well as Lists with Strings. Same problem. Everything comes directly in one entry.
So what can I do?
To send as an Object
This is your ISearchProfilePost.class
#FormUrlEncoded
#POST("/profile/searchProfile")
Call<ResponseBody> postSearchProfile(#Body ArrayListAge ages);
Here you will enter the post data in pojo class
public class ArrayListAge{
#SerializedName("age")
#Expose
private ArrayList<String> ages;
public ArrayListAge(ArrayList<String> ages) {
this.ages=ages;
}
}
Your retrofit call class
ArrayList<Integer> ages = new ArrayList<>();
ages.add(20);
ages.add(30);
ArrayListAge arrayListAge = new ArrayListAge(ages);
ISearchProfilePost iSearchProfile = gsonServerAPIRetrofit.create(ISearchProfilePost.class);
Call<ResponseBody> call = iSearchProfile.postSearchProfile(arrayListAge);
To send as an Array List check this link https://github.com/square/retrofit/issues/1064
You forget to add age[]
#FormUrlEncoded
#POST("/profile/searchProfile")
Call<ResponseBody> postSearchProfile(
#Field("age[]") List<Integer> age
};
Retrofit can do this now at least I tested with this -> implementation 'com.squareup.retrofit2:retrofit:2.1.0'
For example
#FormUrlEncoded
#POST("index.php?action=item")
Call<Reply> updateStartManyItem(#Header("Authorization") String auth_token, #Field("items[]") List<Integer> items, #Field("method") String method);
This is the piece we are looking at.
#Field("items[]") List<Integer> items
I am working on some chat - app whith complex messages.
Messages from API stored in realm DB.
When i getting messages: call after API response, deserialization finished, messages correct:
realm.beginTransaction();
realm.copyToRealmOrUpdate(listOfBaseMessageResponses);
realm.commitTransaction();
messages in db replaced and i forced to make a List in my activity and try to handle changes by myself.
Changes tracked in activity by:
messagesChangedListener = new RealmChangeListener() {
...
}
mBaseMessageResponsesRealm = realm.allObjects(BaseMessageResponse.class);
mBaseMessageResponsesRealm.addChangeListener(messagesChangedListener);
Way to get messages:
return realm.allObjects(BaseMessageResponse.class);
BaseMessageResponse class(getters and setters exists. for better understanding not show):
#SerializedName("clr")
#Expose
#PrimaryKey
private String clr;
#SerializedName("cap")
#Expose
private String cap;
#SerializedName("eoc")
#Expose
private int eoc;
#SerializedName("list")
#Expose
private RealmList<MessageInResponse> list = new RealmList<MessageInResponse>();
...
Also MessageInResponse contain nested classes.
Why messages replaced? I try many ways to figure it out but no result.
May be some problems with PK and logic for copyToRealmOrUpdate method?
I am new in doing work with android database. My question is, I have a json data which i want to parse it in my android application. Specifically i want to take that data and save it in my app database which is ORMLITE.
Does anyone have any example of this so please do share with me. Any kind of video tutorial or anything will be helpful here.
Thanks in advance
I would utilize the GSON library which is super helpful for handling JSON
https://code.google.com/p/google-gson/
Then you need to create a java class with all of the data that the JSON has that you want to parse.
If your JSON looked like this:
{
"id":4854
"name":"Charlie"
"age":35
"eye_color":"blue"
}
Then you would want to create a class matching that data. THIS IS CASE SENSITIVE.
public class Data implements Serializable {
private int id;
private String name;
private int age;
private String eye_color;
}
public class Item implements Serializable{
}
Now you can create a java object from the JSON:
Gson gson = new Gson();
Data data = gson.fromJson(yourJsonHere, Data.class)
and boom! your data object is now what your JSON was.
Ok, I don't use ORMLITE, I'm using GreenDao as ORM but I guess it's the same thing. For parsing a JSON there is some libraries that help, I always try to use GSON that is a library that handle serialization between objects and JSON data. There is a lot of documentation about GSON on the web and plenty of examples. Search for it. I recommend use that approach, for me is the better. Also you can parse a JSON with the org.json.JSON library. This one is more "by hand" parser but could be pretty useful. For example:
for the following JSON:
{
"name": "MyName",
"age": 24
}
that you want to map into a object Person that is a class from your data model generated by ORMLITE:
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
You could do something like:
Person myPerson = new Person();
//This is the use of the org.json.JSON library
JSONObject jObject = new JSONObject(myJSONString);
myPerson.setName(jObject.getString("name"));
myPerson.setAge(jObject.getInt("age"));
And that's a way. Of course JSON library has many function and types to help you with JSON data. Check it out.
But all that code with GSON will be reduced to:
Gson gson = new GsonBuilder().create();
Person myPerson = gson.fromJson(myJSONString, Person.class);
So again try using GSON, it's the best way. Hope it helps