How to define lists in object binded to JSON? - java

I am trying to create an object to bind the JSON response to my object using Jackson Library but I do not know how to define few of the fileds such as category, neighborhoods, location and address.
Sample response from JSON
{"region":
{"span":
{"latitude_delta": 0.10262262794520893, "longitude_delta": 0.22282942},
"center": {"latitude": 51.510372893357001, "longitude": -0.1108336}},
"total": 246, "businesses": [{"is_claimed": false,
"rating": 4.5,
"mobile_url": "http://m.yelp.co.uk/biz/r-garcia-and-sons-foods-and-wines-of-spain-london",
"rating_img_url": "http://s3-media2.ak.yelpcdn.com/assets/2/www/img/99493c12711e/ico/stars/v1/stars_4_half.png",
"review_count": 11,
"name": "R Garcia \u0026 Sons - Foods and Wines of Spain",
"snippet_image_url": "http://s3-media2.ak.yelpcdn.com/photo/8xquccU5FKaFg9ZlANdOJA/ms.jpg",
"rating_img_url_small": "http://s3-media2.ak.yelpcdn.com/assets/2/www/img/a5221e66bc70/ico/stars/v1/stars_small_4_half.png",
"url": "http://www.yelp.co.uk/biz/r-garcia-and-sons-foods-and-wines-of-spain-london",
"phone": "+442072216119",
"snippet_text": "aka R Garcia \u0026 Son, and Cafe Garcia. Although, technically, Cafe Garcia is next door attached to their la carniceria. \n\nIt is a great Spanish grocery store...",
"image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/t14haXQrAW8HMwc0RTL1jQ/ms.jpg",
"categories": [["Delis", "delis"], ["Spanish", "spanish"], ["Beer, Wine \u0026 Spirits", "beer_and_wine"]],
"display_phone": "+44 20 7221 6119",
"rating_img_url_large": "http://s3-media4.ak.yelpcdn.com/assets/2/www/img/9f83790ff7f6/ico/stars/v1/stars_large_4_half.png",
"id": "r-garcia-and-sons-foods-and-wines-of-spain-london",
] "is_closed": false,
"location": {"city": "London", "display_address": ["248-250 Portobello Road", "Notting Hill", "London W11 1LL", "UK"],
"neighborhoods": ["Notting Hill"],
"postal_code": "W11 1LL",
"country_code": "GB",
"address": ["248-250 Portobello Road"],
"state_code": "XGL"}},
{"is_claimed": false, "rating": 3.0, ......
Classes
public class Region {
private Span span;
getter and setter
}
public class Span {
private double latitude_delta;
private double longitude_delta;
private Center center;
private int total;
private Businesses businesses;
getter and setter
}
public class Center {
private double latitude;
private double longtitude;
getter and setter
}
public class Businesses {
private boolean is_claimed;
private double rating;
private String mobile_url;
private String rating_img_url;
private int review_count;
private String name;
private String snipper_image_url;
private String rating_img_url_small;
private String url;
private String phone;
private String snippet_text;
private String image_url;
private categories; <<<<<<<<<<<<<<<<<
private String display_phone;
private String rating_img_url_large;
private String id;
private boolean is_closed;
private Location location; <<<<<<<<
private neighborhoods <<<<<<<<<
private String postal_code;
private String country_code;
private address <<<<<<<<<<
private String state_code;
getters and setters
}

categories: list of lists of starings. You can use array instead of list.
class Location {
String city;
String[] displayAddress; // you can use list instead
}
neighborhoods - I cannot see such field in your json.
String[] address; //or list as in previous case.

Related

Setting data for type array- RestAssured Post Method

I am trying to create a pay load for this body and will do a POST.
{
"location": {
"lat": -38.383494,
"lng": 33.427362
},
"accuracy": 50,
"name": "Frontline house Seattle",
"phone_number": "(1) 952 893 3937",
"address": "29, side layout, cohen 09",
"types": [
"shoe park",
"shop"
],
"website": "http://google.com",
"language": "French-EN"
}
These are the 3 classes I have created
#Getter
#Setter
public class Payload {
private Location location;
private int accuracy;
private String name;
private String phone_number;
private String address;
private List<Types> types;
private String website;
private String language;
}
#Getter
#Setter
public class Location {
private double lat;
private double lng;
}
#Setter
#Getter
public class Types {
private String zero;
private String one;
}
This below will be will be use to do the post
#Test
public void createAddress(){
Location location = new Location(); // Location Class
location.setLat(-38.383494);
location.setLng(33.427362);
Types[] type = new Types[2]; // Type Class
Payload payload = new Payload();
payload.setLocation(location); // This is how we will set the Location type class in Payload
payload.setAccuracy(50);
payload.setName("Frontline house");
payload.setPhone_number("(1) 952 893 3937");
payload.setAddress("29, side layout, cohen 09");
payload.setTypes();
}
Problem: I am not sure how do I set value for Types to create this payload.I also have a feeling I have declared Types incorrectly. In that class I have declared 2 String variables.
Thanks in advance for your suggestion.
You don't have to create a seperate class for types, since it's a list just declare it as a list of strings
#Setter
#Getter
private List<String> types;
The getters and setters for these would be
public List<String> getTypes() {
return types;
}
public void setTypes(List<String> types) {
this.types = types;
}
In your test
List<String> myList =new ArrayList<String>();
myList.add("shoe park");
myList.add("shop");
payload.setTypes(myList);

Is there a way that realm createOrUpdateAllFromJson() could read nested JSONArrays and create inner RealmObjects?

I have the following JSON modelling groups with students:
"groups":[{
"id": "1",
"grade":"second",
"group": "A",
"students":[{
"id": "1",
"address": "rhonda#pugh.no",
"name": "Geoffrey Guthrie",
"phone": "475690",
"parent": "Ronald Zhang",
"diagnosis": "Whitehead",
},
...}],
...}]
and their respective classes are as follows (setters and getters not included):
public class Student extends RealmObject {
private String id;
private String name;
private String address;
private String phone;
private String parent;
private String diagnosis;
}
and:
public class Group extends RealmObject{
private String id;
private String grade;
private String group;
private RealmList<Student> students;
}
My question here is if the method createOrUpdateAllFromJson, as stated above, supports those nested arrays or should I do it manually getting the arrays inside and then call the same function to create the list of students for each group?
No you don't need to manually getting the arrays inside and then call the same function to create the list of students for each group. But you will not be able to use
createOrUpdateAllFromJson() for JOSNArray
or
createOrUpdateObjectFromJson() for JSONObject
Because createOrUpdate requires a primary key. But according to your Json structure there is no primary key for the root object. My code blocks will describe the scenario.
Your Json Structure-
{
"groups":[{
"id": "1",
"grade":"second",
"group": "A",
"students":[{
"id": "1",
"address": "rhonda#pugh.no",
"name": "Geoffrey Guthrie",
"phone": "475690",
"parent": "Ronald Zhang",
"diagnosis": "Whitehead"
}]
}]
}
According this Your Models should be as follows-
public class Students extends RealmObject {
private String id;
private String name;
private String address;
private String phone;
private String parent;
private String diagnosis;
}
and:
public class Groups extends RealmObject {
private String id;
private String grade;
private String group;
private RealmList<Students> students;
}
and:
public class BaseObject extends RealmObject {
private RealmList<Groups> groups;
}
And then your transaction will be like this-
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.createObjectFromJson(BaseObject.class, json);
}
});
You can add #PrimaryKey annotation for Groups and Students id to avoid duplicate entry if necessary. Hope this structure will reduce your hassle.

How to parse a JSON with a property which could be a String or an Object using GSON?

I have a class that should be deserialized accordingly the header request.
If header is on V1 version, ww should output the information field of Product class, like a String. Otherwise it output an Info object.
Is there another solution to do this, instead duplicate the class?
public class Product{
private String name;
private Integer id;
private Info information;
}
public class Info{
private String generalInfo;
private String fullDescription;
private String code;
}
public class Product{
private String name;
private Integer id;
private String information;
}
Above the JSON when use INFO object and when information is a string.
{
"name": "Paul",
"id": "123123,
"information": {
"generalInfo":"Business Product",
"fullDescription":"23",
"code":"9487987289929222-3"
}
}
{
"name": "Paul",
"id": "123123,
"information": "Business Product - 23 - 9487987289929222-3 "
}

Parse JSON to Java Object using GSON

I am trying to map a json document from the jenkins API to my own java objects. The json document looks as follows:
{
"assignedLabels": [
{}
],
"mode": "EXCLUSIVE",
"nodeDescription": "Jenkins Master-Knoten",
"nodeName": "",
"numExecutors": 2,
"description": null,
"jobs": [
{
"name": "Job 1",
"url": "https://build.example.com/jenkins/job/Job1/",
"color": "disabled"
},
{
"name": "Job 2",
"url": "https://build.example.com/jenkins/job/Job2/",
"color": "blue"
}
],
"overallLoad": {},
"primaryView": {
"name": "Alle",
"url": "https://build.example.com/jenkins/"
},
"quietingDown": false,
"slaveAgentPort": 0,
"unlabeledLoad": {},
"useCrumbs": false,
"useSecurity": true,
"views": [
{
"name": "Selection",
"url": "https://build.example.com/jenkins/view/-All%Selection/"
},
{
"name": "All",
"url": "https://build.example.com/jenkins/"
}
]
}
My java model looks like this:
public class JenkinsServer {
private List<String> assignedLabels;
private String url;
private String mode;
private String nodeName;
private String nodeDescription;
private String description;
private boolean useSecurity;
private boolean quietingDown;
private JenkinsServerView primaryView;
private List<JenkinsServerView> views;
private List<JenkinsJob> jobs;
// getters & setters
}
What I am doing now is I call
Gson gson = new Gson();
JenkinsServer server = gson.fromJson( reader, JenkinsServer.class );
But I receive this exception
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 6 column 5
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165)
I've been searching the internet for a solution but could not figure out what I'm doing wrong. Maybe you guys know :-)
As #Gimby mentioned in the comment, the problem is in your json data.
Solution1:
As assignedLabels is an array of strings with empty values, one option is to change the json data without curly braces as follows:
"assignedLabels": []
Solution2:
add transient keyword to the variable in java class
private transient List<String> assignedLabels;
Solution3:
the last and clumsy way to achieve is to add #Expose annotation to the all the variables that you want to parse in your java class
public class JenkinsServer {
private List<String> assignedLabels;
#Expose
private String url;
#Expose
private String mode;
#Expose
private String nodeName;
#Expose
private String nodeDescription;
#Expose
private String description;
#Expose
private boolean useSecurity;
#Expose
private boolean quietingDown;
#Expose
private JenkinsServerView primaryView;
#Expose
private List<JenkinsServerView> views;
#Expose
private List<JenkinsJob> jobs;
// getters & setters methods
}
and then add the parsing logic to parse your json string to corresponding java object as follows:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
JenkinsServer server = gson.fromJson(reader, JenkinsServer.class);

Creating a listview from a nested JSON

I have a JSON file that I fetch from the internet which contains schedule data for a TV channel. Nested within that file, alongside lots of metadata, is info about each broadcast (i.e. each programme) and below is a sample of that file:
For ease of understanding, I recommend this visual representation of the below JSON instead (click on the Viewer tab on the JSON viewer).
{
"schedule": {
"service": {
"type": "tv",
"key": "bbcnews",
"title": "BBC News Channel"
},
"day": {
"date": "2013-11-15",
"has_next": 1,
"has_previous": 1,
"broadcasts": [
{
"is_repeat": false, <=== This is the 1st broadcast programme
"is_blanked": false,
"pid": "p01ks4z3",
"start": "2013-11-15T03:45:00Z",
"end": "2013-11-15T04:00:00Z",
"duration": 900,
"programme": {
"type": "episode",
"pid": "b03hdhhp",
"position": null,
"title": "15/11/2013",
"short_synopsis": "All the latest sports news and results from around the globe.",
"media_type": "audio_video",
"duration": 900,
"display_titles": {
"title": "Sport Today",
"subtitle": "15/11/2013"
},
"first_broadcast_date": "2013-11-15T03:45:00Z",
"ownership": {
"service": {
"type": "tv",
"id": "bbc_news24",
"key": "bbcnews",
"title": "BBC News Channel"
}
},
"programme": {
"type": "brand",
"pid": "b0121xvw",
"title": "Sport Today",
"position": null,
"expected_child_count": null,
"first_broadcast_date": "2011-06-13T02:45:00+01:00",
"ownership": {
"service": {
"type": "tv",
"id": "bbc_news24",
"key": "bbcnews",
"title": "BBC News Channel"
}
}
},
"is_available_mediaset_pc_sd": false,
"is_legacy_media": false
}
},
{
"is_repeat": false, <=== This is the 2nd broadcast programme
"is_blanked": false,
"pid": "p01ks4z4",
"start": "2013-11-15T04:00:00Z",
"end": "2013-11-15T04:30:00Z",
"duration": 1800,
"programme": {
"type": "episode",
"pid": "b03hdhhs",
"position": null,
"title": "15/11/2013",
"short_synopsis": "Twenty-four hours a day, the latest national and international stories as they break.",
"media_type": "audio_video",
"duration": 1800,
"display_titles": {
"title": "BBC News",
"subtitle": "15/11/2013"
},
"first_broadcast_date": "2013-11-15T04:00:00Z",
"ownership": {
"service": {
"type": "tv",
"id": "bbc_news24",
"key": "bbcnews",
"title": "BBC News Channel"
}
},
"programme": {
"type": "brand",
"pid": "b006mgyl",
"title": "BBC News",
"position": null,
"expected_child_count": null,
"first_broadcast_date": "2006-11-01T13:00:00Z",
"ownership": {
"service": {
"type": "tv",
"id": "bbc_news24",
"key": "bbcnews",
"title": "BBC News Channel"
}
}
},
"is_available_mediaset_pc_sd": false,
"is_legacy_media": false
}
}
]
}
}
}
Using the answer to this question on StackOverflow, I created a Javabean class like so:
private class ScheduleData {
private Schedule schedule;
// create getter & setter
public static class Schedule {
private Service service;
private Day day;
// create getter & setter
}
public static class Service {
private String type;
private String key;
private String title;
// create getter & setter
}
public static class Day {
private String date;
private String has_next;
private String has_previous;
private Broadcasts broadcasts;
// create getter & setter
}
public static class Broadcasts {
private String is_repeat;
private String is_blanked;
private String pid;
private String time;
private String end;
private String duration;
private OuterProgramme programme;
// create getter & setter
}
public static class OuterProgramme {
private String type;
private String pid;
private String position;
private String title;
private String short_synopsis;
private String media_type;
private String duration;
private String first_broadcast_date;
private DisplayTitles display_titles;
private Ownership ownership;
private InnerProgramme programme;
// create getter & setter
}
public static class DisplayTitles {
private String title;
private String subtitle;
// create getter & setter
}
public static class Ownership {
private Service service;
// create getter & setter
}
public static class Service {
private String type;
private String id;
private String key;
private String title;
// create getter & setter
}
public static class InnerProgramme {
private String type;
private String pid;
private String title;
private String position;
private String expected_child_count;
private String first_broadcast_date;
private Ownership ownership;
private String is_available_mediaset_pc_sd;
private String is_legacy_media;
// create getter & setter
}
}
In my activity file, how do I loop through each broadcast node of the fetched JSON and retrieve programme data such as short_synopsis or display_titles and pass these into a custom listview display?
1) Define root Json Wrapper class ScheduleData.java
public class ScheduleData {
private Schedule schedule;
public Schedule getSchedule() {
return schedule;
}
}
2) Define its properties as seperate public classes:
2.a) Schedule.java
public class Schedule {
private Service service;
private Day day;
// TODO: create other getters & setters if you need
public Day getDay() {
return day;
}
}
2.b) Service.java
public class Service {
private String type;
private String id;
private String key;
private String title;
// TODO: create getters & setters if you need
}
2.c) Day.java
public class Day {
private String date;
private int has_next;
private int has_previous;
private Broadcast[] broadcasts;
// TODO: create other getters & setters if you need
public Broadcast[] getBroadcasts() {
return broadcasts;
}
}
2.d) Broadcast.java
public class Broadcast {
private boolean is_repeat;
private boolean is_blanked;
private String pid;
private String start;
private String end;
private int duration;
private Programme programme;
// TODO: create other getters & setters if you need
public Programme getProgramme() {
return programme;
}
}
2.e) Programme.java
public class Programme {
private String type;
private String pid;
private String position;
private String title;
private String short_synopsis;
private String media_type;
private int duration;
private String first_broadcast_date;
private DisplayTitle display_titles;
private Ownership ownership;
private Programme programme;
// TODO: create other getters & setters if you need
public String getShort_synopsis() {
return short_synopsis;
}
public DisplayTitle getDisplay_titles() {
return display_titles;
}
}
2.f) DisplayTitle.java
public class DisplayTitle {
private String title;
private String subtitle;
// create getter & setter
}
2.g) Ownership.java
public class Ownership {
private Service service;
// create getter & setter
}
3) Define an AsyncTask and call json service. Get result as stream and set its value to a ScheduleData instance using gson library. (I assume you know how to call json service on android, but if you don't it is a 5 min googling issue.)
HttpEntity getResponseEntity = getResponse.getEntity();
InputStream source = getResponseEntity.getContent();
Gson gson = new Gson();
Reader reader = new InputStreamReader(source);
ScheduleData scheduleData = gson.fromJson(reader, ScheduleData.class);
4) Now you have a ScheduleData instance. It is filled by service's json response.
Schedule schedule = scheduleData.getSchedule();
Day day = schedule.getDay();
Broadcast[] broadCastArr = day.getBroadcasts();
// TODO: use your broadCastArr in an adapter

Categories