I'm a newbie in Retrofit. How to parse the Json below using retrofit?
{
"data": {
"Aatrox": {
"id": 266,
"title": "a Espada Darkin",
"name": "Aatrox",
"key": "Aatrox"
},
"Thresh": {
"id": 412,
"title": "o GuardiĆ£o das Correntes",
"name": "Thresh",
"key": "Thresh"
}
},
"type":"champion",
"version":"6.23.1"
}
You could make your model POJO contain a Map<String, Champion> to deserialize into, to deal with the dynamic keys.
Example:
public class ChampionData {
public Map<String, Champion> data;
public String type;
public String version;
}
public class Champion {
public int id;
public String title;
public String name;
public String key;
}
I'm not familiar with Retrofit besides that, but as someone in the comments said, the deserializing is done by Gson:
public ChampionData champions = new Gson().fromJson(json, ChampionData.class);
So to build on to the answer someone else posted, you can then do the following, assuming you've added the GsonConverterFactory:
public interface API {
#GET("path/to/endpoint")
Call<ChampionData> getChampionData();
}
Assuming Retrofit2, the first thing you need to do is call following when building your Retrofit instance.
addConverterFactory(GsonConverterFactory.create())
Then it's just a matter of writing a POJO (e.g. MyPojoClass) that maps to the json and then adding something like following to your Retrofit interface.
Call<MyPojoClass> makeRequest(<some params>);
Related
I'm trying to parse a JSON object using retrofit 2.0 following this guide, but it doesn't work. I think it's because of a difference in JSON format.
Here is a nested JSON object with the format:
{
"SearchService": {
"list_total_count": 531,
"RESULT": {
"CODE": "INFO-001",
"MESSAGE": "SUCCESS"
},
"row": [{
"ID": "1983",
"NAME": "SAN",
"NUM": "38",
}, {
"ID": "1984",
"NAME": "DU",
"NUM": "27",
}]
}
}
Here is class code using SerializedName:
RowList.java
public class RowList {
#SerializedName("row")
#Expose
private ArrayList<Row> rows= new ArrayList<>();
public ArrayList<Row> getRows() {
return rows;
}
public void setRows(ArrayList<Row> rows) {
this.rows= rows;
}
}
Row.java
public class Row{
#SerializedName("ID")
#Expose
private String id;
#SerializedName("NAME")
#Expose
private String name;
#SerializedName("NUM")
#Expose
private String num;
/*getter setter*/
}
Read that guide.
There are two approaches to create Model class. The first way is the manual approach, which requires you to learn how to use the Gson library. The second approach is you can also auto-generate the Java classes you need by capturing the JSON output and using jsonschema2pojo
Looks like you've attempted approach one, but haven't (yet?) tried reading over the Gson documentation.
Okay, you have a Row. That covers the objects within "row": [...], so you also need objects for the following:
"SearchService": {}
"RESULT": {}
I don't think the RowList class is necessary. List<Row> is fine.
For example,
class Result {
#SerializedName("CODE")
String code;
#SerializedName("MESSAGE")
String message;
}
class SearchService {
#SerializedName("list_total_count")
long count;
#SerializedName("RESULT")
Result result;
#SerializedName("row")
private ArrayList<Row> rows= new ArrayList<>();
}
(removed #Expose for conciseness)
Then, Retrofit would use Call<SearchService>
I want to parse JSON Array and display result in listview. I have already ask in this community but didn't get helpful answer. Please give me code for this JSON.
JSON
[{
"city_id": "1",
"city_name": "Noida"
},
{
"city_id": "2",
"city_name": "Delhi"
},
{
"city_id": "3",
"city_name": "Gaziyabad"
},
{
"city_id": "4",
"city_name": "Gurgaon"
},
{
"city_id": "5",
"city_name": "Gr. Noida"
}]
URL
http://14.140.200.186/Hospital/newget_city.php
please help
As mentioned the question is too broad, just to give the approach I would take.
Build the model class in this case: City
I would advise using retrofit(http://square.github.io/retrofit/) for the network call, so build the interface
Make the network call
Add the retrieved results in a recyclerview adapter
Using Gson can do the json parsing job for you. Its easy to integrate and handy to parse json data. You simply need to create a class containing city_id and city_name.
City.java
public class City {
private String city_id;
private String city_name;
public City() {
}
public String getCityId() {
return city_id;
}
public String getCityName() {
return city_name;
}
}
Now add another class. E.g. CityList.java
import java.util.List;
public class CityList {
private List<City> cityList;
public CityList() {
}
public List<City> getCityList() {
return cityList;
}
}
Now from json string, parse the data into the CityList class.
Gson gson = new Gson();
CityList myCityList = gson.fromJson(jsonString, CityList.class);
Add the gradle dependency for Gson in build.gradle
compile 'com.google.code.gson:gson:2.3'
I've been using Retrofit library recently and I like it so far. However, I've come across API that returns response with the following structure:
"data":
{
"meta":
{
"code": 200
"data": "data"
},
"body": [
{
"id": "id",
"field1": "data",
"field2": "data"
},
{
"id": "id",
"field1": "data",
"field2": "data"
}]
}
Assuming I have following class:
public class Entity {
long id;
String field1;
String field2;
}
and following interface:
public interface EntityService {
#GET("/api/method")
void getEntities(Callback<List<Entity>> callback);
}
what is the correct way to use Retrofit if I want to get a list of Entity objects from data.body element from response? I know I could have passed Response object in the callback and manually parse it using org.json package or something else, but is there any better way?
Why not just make a class that represents the data like you've already half done? That's what I've done in multiple apps along with other developers:
public class Meta {
String code;
String data;
}
public class Data {
Meta meta;
List<Entity> body;
}
public interface EntityService {
#GET("/api/method")
void getEntities(Callback<Data> callback);
}
It seems that extra data in your result could be re-used. You should use a generic class like this one:
public class Data<E> {
Meta meta;
E body;
public static class Meta {
int code;
String data;
}
}
Then you could use
Data<List<Entity>>
or whatever you want:
public interface EntityService {
#GET("/api/method")
void getEntities(Callback<Data<List<Entity>>> callback);
}
Trying out Gson for the first time instead of looping through the JSON objects for speed.
This is my input data set for parsing
{
"data": [
{
"access_token": "XXXXX",
"category": "Community",
"name": "Startup notes by Vrashabh",
"id": "XXXXX",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
{
"access_token": "XXXX",
"category": "Community",
"name": "Clean Bangalore",
"id": "XXXXX",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
{
"access_token": "XXXXX",
"category": "Internet/software",
"name": "Getmeetin",
"id": "XXXXX",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
}
],
"paging": {
"cursors": {
"before": "MTU3MzE3MTA0MjkyMjY4MQ==",
"after": "MjcyMTIwMzE2Mjk3NzI5"
}
}
}
And this is my gson mapping class
public class AccountsResponse {
ArrayList<AcResponseData> data;
ArrayList<PagingData> paging;
public class AcResponseData {
public String access_token;
public String category;
public String name;
public String id;
public String[] perms;
}
public class PagingData{
public Cursors cursors;
}
public class Cursors{
public String before;
public String after;
}
}
Code for parsing the data
AccountsResponse responseAccounts = gsonResponse.fromJson(response.getRawResponse(), AccountsResponse.class);
I Know I am supposed to not expect magic in terms of data conversion, I found the other questions on SO that ask me to implement TypeToken but I couldn't get it working for this case. How do I use TypeToken to get this data into the ORM
I wouldn't mind not reading that paging data also actually, if that needs to be eliminated from the ORM
UPDATE
Changed the ORM as below but now I get
java.lang.StackOverflowError
The problem is in your AccountsResponse class. It should be an object PagingData not an ArrayList, because from the json response in your question, "paging" is a JSON object not a JSON array. So, you should declare paging as a PagingData object not as an ArrayList of PagingData objects. That should fix it.
public class AccountsResponse {
ArrayList<AcResponseData> data;
PagingData paging;
public class AcResponseData {
public String access_token;
public String category;
public String name;
public String id;
public String[] perms;
}
public class PagingData{
public Cursors cursors;
}
public class Cursors{
public String before;
public String after;
}
}
Let me know if this helps.
So I'm working with retrofit with an API that has a variable called "public". How would I go about getting it to automatically map like all the other variables do.
Example:
#GET("/?filter=my_images")
void getMyImages(
#Query("client_id") String id,
#Query("api_key") String key,
Callback<ImageList> callback
);
public static class Image{
int id;
String name;
String distribution;
String slug;
// Can't do this:
boolean public;
}
public static class ImageList{
String status;
List<Image> images;
}
Example API results (json):
{
"status": "OK",
"images": [
{
"id": 1,
"name": "My first snapshot",
"distribution": "Ubuntu",
"slug": "ubuntu-12.10-x32",
"public": true
},
{
"id": 2,
"name": "Automated Backup",
"distribution": "Ubuntu"
}
]
}
Retrofit uses Gson for serialization to and from JSON.
Gson provides a #SerializedName annotation in order to change the key to which a field or method is mapped. You can use this for handling your reserved word:
#SerializedName("public")
public String isPublic;
Please look at this link, which is a neater solution if there are underscores in each key.