Reputation: 109
I am trying to parse a JSON URL with Retrofit 2 for my Android project and I have a question. In my URL the JSON look like this:
{
"channel0":{
"song":"Crush",
"artist":"Jennifer Paige",
"duration":"180",
"playedat":"1545065265",
"image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/8eecc92227fcbb09b43472f000df74e1.png"
},
"channel1":{
"song":"Reasons Why",
"artist":"Brand New Immortals",
"duration":"180",
"playedat":"1545065371",
"image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/c059afda95dd35354af26cf72e5deab4.png"
},
"channel2":{
"song":"Dance Me To The End Of Love",
"artist":"Leonard Cohen",
"duration":"300",
"playedat":"1545065181",
"image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/a368617dc7dc4716a9badb523ff6e7d4.png"
},
"channel3":{
"song":"4 Minutes",
"artist":"Madonna",
"duration":"180",
"playedat":"1545065300",
"image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/1dcefc6496be4155a00f919dcbb54f77.png"
},
"channel4":{
"song":"Mothers, Sisters, Daughters",
"artist":"Voxtrot",
"duration":"180",
"playedat":"1545065257",
"image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/5861b97231bd4ffe9218dfcacc27d68a.png"
}
}
And when I use POJO, it creates multiple classes for every channel. So what is the proper way of handling this JSON URL?
Upvotes: 1
Views: 1425
Reputation: 3535
First: this is not called JSON URL... it's simple JSON, or JSON data if you want... URL and JSON are two totally separated things
Second: is not clear what you mean when you say:
And when I use POJO, it creates multiple classes for every channel. So what is the proper way of handling this JSON URL?
If you are generating Java classes from any JSON to POJO tool this is a normal behavior since no tool has how to guess that channel2
is the same thing as channel3
as JSON instances they can be two totally different things, there is no way to know.
The right way is to design your Java classes first and then map the JSON, not the opposite.
Upvotes: 0
Reputation: 54204
Every JSON object can also be considered a Map
of strings to JSON elements. In cases like this, where you're going to get an object with dynamic key names, you don't have to try to build a Java class to represent it. You can just use Map<String, Object>
instead.
In this case, you know that each value will be a song, so you can be a little more specific than Object
.
Start by defining e.g. a Song
class to hold the inner elements:
public class Song {
public String song;
public String artist;
...
}
And then you'd make your call and loop over the result:
Call<Map<String, Song>> call = ...
call.enqueue(new Callback<Map<String, Song>>() {
@Override
public void onResponse(Response<Map<String, Song>> response) {
Map<String, Song> body = response.body();
for (Song song : body.values()) {
// your code here
}
}
@Override
public void onFailure(Throwable t) {
// TODO
}
});
You can even turn it into a list of songs if you need to for some reason:
List<Song> songs = new ArrayList<>(body.values());
Upvotes: 3