Creating a listview from a nested JSON - java

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

Related

How to create Java classes using the reusable json attributes in Jackson?

I need to convert below JSON to Java classes
Here is the JSON
{
"browserName": "chrome",
"env": "test",
"envUrls1": {
"qatesta": {
"fName": "test",
"lName": "test",
"email": "3242342",
"password": "passTestaa"
},
"qatestb": {
"fName": "test",
"lName": "test",
"email": "3242342",
"password": "passTestaa"
},
"qatestc": {
"fName": "test",
"lName": "test",
"email": "3242342",
"password": "passTestaa"
}
}
}
Using above JSON body I able to creates below classes.
1.
public class JsonConfMainObj {
private String browserName;
private String env;
private EnvUrls1 envUrls1;
}
2.
public class EnvUrls1 {
private Qatesta qatesta;
private Qatestb qatestb;
private Qatestc qatestc;
}
3. In each above 'Qatesta', 'Qatestb' and 'Qatestc' Java Classes Contains the below-repeated values
public class Qatestx{
private String fname;
private String lname;
private String email;
private String password;
}
But I need to avoid repeating the above attributes in each class and move them to common Class and map to 'Qatesta', 'Qatestb', and 'Qatestc'.
like below
public class Qatesta{
private Common com;
}
public class Qatestb{
private Common com;
}
public class Qatestc{
private Common com;
}
public class Common{
private String fname;
private String lname;
private String email;
private String password;
}
Is there a way to do this?
You Can use only One class and give the different variable assigned for that class for eg in EnvUrls1 give class Qatest assigned 3 different values
1.
public class JsonConfMainObj {
private String browserName;
private String env;
private EnvUrls1 envUrls1;
}
2.
public class EnvUrls1 {
private Qatest qatesta;
private Qatest qatestb;
private Qatest qatestc;
}
public class Qatest{
private String fname;
private String lname;
private String email;
private String password;
}

How to get data from retrofit when data is like this as given below

When I try to get name while parsing the response from the server, I am getting null. Can u please help me to get data i.e, name, email and keyskills.name?
The JSON response is here.
{
"freelancer": {
"id": 3,
"name": "trinadh",
"title": "web developer",
"email": "trinadh_freelancer#gmail.com",
"gender": "Male",
"dob": "2018-09-27",
"website": "www.trinadh_freelancer.com",
"country": "India",
"state": "Karnataka",
"city": "Bangalore",
"user_id": 52,
"user_role": "freelancer",
"registered": null,
"agreement": true,
"address": "hsr layout",
"qualification": "b.tech",
"total_experience": "2",
"prefered_location": "",
"category": "Web Development",
"pancard_number": "ajhfvbqjhe",
"passport_number": "hbhfjdhbjfh",
"country_code": null,
"contact_number": "8765456721",
"currency_type": "INR",
"rate": "678.0",
"rate_card_type": "per_hour",
"negotiable": true,
"taxes": "Taxes Excluded",
"key_skills": {
"name": "ruby",
"relevant_experience": "2"
},
"other_skills": {
"name": "animation",
"relevant_experience": "3"
},
"confirmed_at": "24-Sep-2018",
"free_trail_days_left": 83,
"renewal_date": "24-Mar-2019",
"image": "<img src=\"\" />"
}
}
Here is my pojo class
public class FreeLancer {
private List<FreeLancerProfile> freelancer;
// Constructors, getters and setters are removed for convenience
}
Here is my freelancer profile
public class FreeLancerProfile {
private int id;
private String name;
private String title;
private String email;
private String gender;
private String dob;
private String website;
private String country;
private String state;
private String city;
private int user_id;
private String user_role;
private String registered;
private String agreement;
private String address;
private String qualification;
private String total_experience;
private String prefered_location;
private String category;
private String pancard_number;
private String passport_number;
private String country_code;
private String contact_number;
private String currency_type;
private String rate;
private String rate_card_type;
private String negotiable;
private String taxes;
private List<KeySkill> key_skills;
private List<OtherSkill> other_skills;
private String confirmed_at;
private String free_trail_days_left;
private String renewal_date;
private String image;
// Constructors, getters and setters are removed for convenience
}
My Pojo class for key skills
public class KeySkill {
private int id;
private String name;
private String relevant_experience;
// Constructors, getters and setters are removed for convenience
}
My Interface
public interface FreeLancerMainApi {
#GET("{fullUrl}/profile")
Call<FreeLancerProfile> freeLancerMain(
#Path(value = "fullUrl", encoded = true) String fullUrl,
#Header("Authorization") String token
);
#GET("{fullUrl}/profile")
Call<KeySkill> keySkillsMain(
#Path(value = "fullUrl", encoded = true) String fullUrl,
#Header("Authorization") String token
);
}
My Main Avtivity
String BASE_URL = "http://74.207.233.160/api/v1/freelancers/";
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
final FreeLancerMainApi api = retrofit.create(FreeLancerMainApi.class);
Call<FreeLancerProfile> call = api.freeLancerMain(freelancer_id, token);
call.enqueue(new Callback<FreeLancerProfile>() {
#Override
public void onResponse(Call<FreeLancerProfile> call, Response<FreeLancerProfile> response) {
if (response.code() == 200)
{
name = response.body().getName();
email = response.body().getEmail();
contactNumber = response.body().getContact_number();
Toast.makeText(FreelancerActivity.this, name, Toast.LENGTH_SHORT).show();
}
else {
}
}
#Override
public void onFailure(Call<FreeLancerProfile> call, Throwable t) {
}
});
Call<KeySkill> call1 = api.keySkillsMain(freelancer_id, token);
call1.enqueue(new Callback<KeySkill>() {
#Override
public void onResponse(Call<KeySkill> call, Response<KeySkill> response) {
if (response.code() == 200){
skills = response.body().getName();
}else {
}
}
#Override
public void onFailure(Call<KeySkill> call, Throwable t) {
}
});
freeLancerMainName.setText(name);
freeLancerMainEmail.setText(email);
freeLancerContactNumber.setText(contactNumber);
freeLancerKeySkills.setText(skills);
I am getting null response as when I execute this code. Please help and thanks in advance!
As I can see from the response, it is not returning an array or a list. However, as far as I have understood from your code, you are expecting to parse the response into a list.
The Freelancer pojo should look like the following.
public class FreeLancer {
public FreeLancerProfile freelancer;
}
If everything else is okay, it should work fine.
UPDATE:
The response should be bound to FreeLancer class, not to FreeLancerProfile class. I have shown an example, which might help. Please check.
public void onResponse(Call<FreeLancer> call, Response<FreeLancer> response) {
if (response.code() == 200) {
FreeLancer freelancer = response.body();
name = freelancer.getName();
email = freelancer.getEmail();
// Others ...
}
}
And in your FreelancerProfile pojo, you need to remove the List from the key_skills and other_skills as well. These are not lists as well.
private KeySkill key_skills;
private OtherSkill other_skills;

How to parse JSON with Jackson2 when Object-Key is random?

I want to parse a JSON in Java with Jackson2 which has the the following structure:
{
"attachment": {
"_2K26Z-mLJmMSRnssLwD0zQ": {
"ext": "jpg",
"height": 3024,
"md5": "219c226e0070b7367f90e2f1bff1dfc2",
"name": "IMG_1871.jpg",
"ref": "MTUyMTAzNDY5MDUzNElNR18xODcxLmpwZw==",
"rotate": true,
"size": 1514957,
"thumb": "thumb_1024_219c226e0070b7367f90e2f1bff1dfc2",
"thumb_size": 73119,
"type": "image",
"width": 4032
},
"_Q7l14s87UquHcAYoolNCuw": {
"ext": "png",
"height": 186,
"md5": "75023fd60d59907376943bf109858336",
"name": "ns_attach_image_26071520280535225.png",
"ref": "MTUyMDI4MDUzNTIzMG5zX2F0dGFjaF9pbWFnZV8yNjA3MTUyMDI4MDUzNTIyNS5wbmc=",
"rotate": true,
"size": 15182,
"type": "image",
"width": 347
}
},
"title": "Test Title"
}
My problem is that I do not know how to handle the key of the attachments, because I can not define a class with the field with unknown name.
What works is
ObjectMapper mapper = new ObjectMapper();
Note note = mapper.readValue(fileio, Note.class);
where the class Note is
public class Note {
private String title;
private Object attachment;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Object getAttachment() {
return attachment;
}
public void setAttachment(Object attachment) {
this.attachment = attachment;
}
}
But I'd like to use an class with Name Attachment which holds all the fields in the json with the key "_2K26Z-mLJmMSRnssLwD0zQ".
You can use a Map, so that a key of an attachment would be a key in the map, and value in the map would be an object representing fields of the attachment. Like this:
public class Attachment {
private String ext;
private int height;
private String md5;
private String name;
private String ref;
private boolean rotate;
private int size;
private String thumb;
private int thumb_size;
private String type;
private int width;
}
public class Note {
private String title;
private Map<String, Attachment> attachment = new HashMap<>();
}

Gson calls returns empty objects over multiple classes

I'm trying to serialize to serialize the json string I have included below.
{
"mood": {
"is_featured": true,
"description": null,
"title": "2014 ",
"ordering": null,
"is_recently_modified": true,
"is_test": false,
"tracks": [
{
"album": {
"release_date": "2014-11-06",
"id": 359778,
"name": "Amansız Gücenik"
},
"name": "Hırpalandı Mayıs",
"artist": {
"id": 491169,
"name": "Ceylan Ertem"
},
"duration": 227,
"isrc": "TRA161400207",
"id": 3903997
},
{
"album": {
"release_date": "2013-08-05",
"id": 329129,
"name": "For Fuld Musik - 25 Danske Sommer Pop & Rock Hits Vol. 2"
},
"name": "Am I Wrong",
"artist": {
"id": 755957,
"name": "Nico & Vinz"
},
"duration": 387,
"isrc": "NO2G31301011",
"id": 3655085
}
],
"image_url": "some_url",
"is_recently_created": true,
"id": 128
}
}
I'm using this gson call to serialize it
Mood mood = new Gson().fromJson(result, Mood.class);
My class structers are like this.
public class Mood {
private boolean is_featured;
private boolean is_recently_modified;
private boolean is_recently_created;
private boolean is_test;
private String description;
private String title;
private String image_url;
private int id;
private int ordering;
private Track[] tracks;
public static class MoodContainer {
public Mood[] moods;
}
}
public class Track {
//variables
private Album album;
private Artist artist;
private Provider provider;
private String secure_url;
private String name;
private String region;
private String isrc;
private int duration;
private int track_order;
private int id;
}
And it goes on like this for any additional class variable. When I try to use the above call I end up with objects that have all null values. One thing to notice is some fields are not supplied in json string because different api calls supply different parts of these json strings. What I am doing wrong?
Root JSON object you provided has property mood - so you either have two options for deserialization to work properly:
Wrap your Mood class inside another object like this:
public class MoodWrapper { private Mood mood; }
and change de-serialization code to
MoodWrapper moodWrapper = new Gson().fromJson(result, MoodWrapper.class);
Skip a root object when deserializing:
final Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonObject rootObj = parser.parse(json).getAsJsonObject();
Mood mood = gson.fromJson(rootObj.getAsJsonObject("mood"), Mood.class);
The top-level elements in the JSON string should be your object's properties, not the outer element "mood" which you have.

How to define lists in object binded to JSON?

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.

Categories