Retrofit map json variable to keyword - android

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.

Related

GSON parsing nested JSON objects differently depending on the environnement

I have a nested JSON object, for example :
{
"references": [
"CONTRACT",
"DURATION",
"EDUCATIONLEVEL",
"EXPERIENCELEVEL",
"LANGUAGELEVEL",
"CIVILITY",
"AVAILABILITY"
],
"unavailablenetworks": [
{
"content": "Service unavailable",
"id": "100"
},
{
"content": "Service unavailable",
"id": "200"
}
],
"urls": {
"apiurl": "https://xxxxxxxxxxx",
"base": "https://yyyyyyyyyyyyyy",
"video": "https://zzzzzzzzzzzzz"
}
}
and the following Java classes :
public class Version implements Serializable {
#SerializedName("references")
private List<String> references;
#SerializedName("unavailablenetworks")
private List<UnavailableNetwork> unavailableNetworks;
#SerializedName("urls")
private BKUrls urls;
}
public class BKUrls implements Serializable {
#SerializedName("apiurl")
private String api;
#SerializedName("base")
private String base;
#SerializedName("video")
private String video;
#SerializedName("edition")
private String edition;
#SerializedName("offer")
private String offer;
#SerializedName("search")
private String search;
}
public class UnavailableNetwork implements Serializable {
#SerializedName("content")
private String content;
#SerializedName("id")
private String id;
}
Getter and Setter methods are omitted here to simplify reading.
I use GSON to parse the JSON :
Gson g = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
Version version = g.fromJson(json.toString(), Version.class);
This code is using in an Android application that I'm developping.
If I install and run the application on an Android Smartphone in debug mode using Android Studio, Gson parses the Json Object correctly.
But If I try to generate an apk and then, install that apk on the same smartphone, Gson does not parse the JSON entirely. The result is like this :
{
"references": [
"CONTRACT",
"DURATION",
"EDUCATIONLEVEL",
"EXPERIENCELEVEL",
"LANGUAGELEVEL",
"CIVILITY",
"AVAILABILITY"
],
"unavailablenetworks": [
{
"id": "100"
},
{
"id": "200"
}
],
"urls": {
}
}
"references" is ok
"unavailablenetworks" is incomplete, missing "content" field
"urls" is empty
I don't understand why Gson doesn't work the same ? Why some data are missing using apk while using Android Studio in debug mode all data are ok ?

How to split a JSON message and convert it to a Singleton class

I'm new using this especial classes.
My problem is:
I recieve in a variable this JSON message:
String buffer = stringBuilder.toString();
String Buffer is this information. It has a list of empresas (Bussiness) and one parameter is a List of Proyects(that has two variables: money and information).
[
{
"name": "LOL",
"address": "LCS",
"phonenumber": 98987845,
"email": "david#gmail.com",
"creditcard": "7674774",
"proyects": [
{
"money": 30000,
"information": "This is my proyect",
"id": 1
},
{
"money": 0,
"information": "My second proyect",
"id": 2
}
],
"id": 1
},
{
"name": "UPC",
"address": "Castelldefels",
"phonenumber": 93245098,
"email": "aasasaasa#gmail.com",
"creditcard": "asdfg9876",
"proyects": [],
"id": 2
}
]
So then i create 3 java.class:
For example the class User is the following:
package com.example.david.dhl;
import java.util.List;
class User {
static String name;
static String password;
static List<Empresa> Empresas;
private static final Usuario ourInstance = new Usuario();
static Usuario getInstance() {
return ourInstance;
}
public String getname() {
return nombre;
}
public String getPassword() {
return password;
}
private User() {
}
}
How can i save all the information in the different singleton classes?
When i do this:
String a = User.getInstance().name;
It said that is empty.
Thank you very much.
PD: if any moderator can put the code more visual will be so nice, because i'm new and i don't find anything. Thank you.
Look at this answer
What you have to do is convert the string into a json array and then with a for loop iterate and the logic in each iteration.

JSON object parsing using retrofit2.0

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>

Retrofit parse JSON dynamic keys

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>);

How do I get a foreign key's field using Retrofit and Gson?

I have an api endpoint which outputs this json for an event table
{
"name": "",
"time": null,
"event_pic_url": null,
"description": "",
"event_type": null,
"invite_only": false,
"free": false,
"age_restriction": false,
"ticket_price": null,
"venue": null
}
The venue field is a foreign key to a Venue table that has this format.
{
"name": "",
"rating": null,
"longitude": null,
"latitude": null
}
After getting the list of events, I would like to get them on a recyclerview (I can already get the list and know how to use an adapter)but I don't want to show the venue's {id}, I want to use the venue's {name}. How do I do this? Is it related to how nested json is deserialized?
After all the comments I will assume that now you have something like:
{
"name": "",
"time": null,
"event_pic_url": null,
"description": "",
"event_type": null,
"invite_only": false,
"free": false,
"age_restriction": false,
"ticket_price": null,
"venue": {
"name": "",
"rating": null,
"longitude": null,
"latitude": null
}
}
Since you're using Gson, you'll want to have the following models
public class Venue {
#SerializedName("name")
#Expose
private String name;
#SerializedName("rating")
#Expose
private Integer rating;
#SerializedName("longitude")
#Expose
private Double longitude;
#SerializedName("latitude")
#Expose
private Double latitude;
// ...
}
public class Event {
#SerializedName("name")
#Expose
private String name;
#SerializedName("time")
#Expose
private String time;
#SerializedName("event_pic_url")
#Expose
private String eventPicUrl;
#SerializedName("description")
#Expose
private String description;
#SerializedName("event_type")
#Expose
private String eventType;
#SerializedName("invite_only")
#Expose
private Boolean inviteOnly;
#SerializedName("free")
#Expose
private Boolean free;
#SerializedName("age_restriction")
#Expose
private Boolean ageRestriction;
#SerializedName("ticket_price")
#Expose
private Double ticketPrice;
#SerializedName("venue")
#Expose
private Venue venue;
// ...
}
Please note that I'm assuming some data types here, i.e., for latitude and longitude as well as event_type. Since in the json they were null I couldn't really be sure, but I guess you can understand from this example. Also please add the appropriate getters and setters.
I want you to focus on the venue part. As you see I'm basically recreating the "nested" json part in Java objects. And that's just it, Gson and retrofit will do the rest for you. Here's how. A word of caution - This may vary a lot depending on how you're doing things. I prefer rxjava, but I'll use the callback approach here since it's easier to explain.
Retrofit 1.9 you can do:
public interface EventService {
#GET("/url/to/events/endpoint/")
public void get(Callback<Event> callback);
}
Provided everything goes well, on the success method of your callback you'll get an instance of Event where you can access the Venue object provided the returned json is actually the one above.
Retrofit 2 the interface changes a bit, but essentially it's the same idea as before:
public interface EventService {
#GET("/url/to/events/endpoint/")
public Call<Event> get();
}
Once you enqueue the request and define the Callback object you will also get an Event object in your success method that would have a reference to a venue. Here's how these callbacks might be implemented with Retrofit 2 (Might slightly change between retrofit versions. I don't fully remember):
eventService.get().enqueue(new Callback<Event>() {
#Override public void onResponse(Call<Event> call, Response<Event> response) {
if (!response.isSuccessful()) {
// Handle http error
return;
}
Event event = response.body();
Venue venue = event.getVenue();
// do something with it
}
#Override public void onFailure(Call<Event> call, Throwable t) {
// Handle error
}
});
}
Here eventService is an object created by Retrofit.create(EventService.class).
Again the retrofit bit might change depending which method you want to use. Important is to understand how you map from the json response to the java objects and basically you just need to replicate the same json structure but in java objects. Hope it helps.

Categories

Resources