I have the following JSON
{
"ads": [
{
"228029_228029": {
"ad_id": "228029",
"duration": 10,
"m3u8_text": {
"_1280p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:7\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.120000,\n_1280p_0000.ts\n#EXTINF:2.880000,\n_1280p_0001.ts\n#EXT-X-ENDLIST\n",
"_320p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:7\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.120000,\n_320p_0000.ts\n#EXTINF:2.880000,\n_320p_0001.ts\n#EXT-X-ENDLIST\n"
}
}
},
{
"228845_228845": {
"ad_id": "228845",
"duration": 24,
"m3u8_text": {
"_1280p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:8\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.840000,\n_1280p_0000.ts\n#EXTINF:6.880000,\n_1280p_0001.ts\n#EXTINF:6.680000,\n_1280p_0002.ts\n#EXTINF:2.600000,\n_1280p_0003.ts\n#EXT-X-ENDLIST\n",
"_320p": "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ALLOW-CACHE:YES\n#EXT-X-TARGETDURATION:8\n#EXT-X-MEDIA-SEQUENCE:0\n#EXTINF:7.840000,\n_320p_0000.ts\n#EXTINF:6.880000,\n_320p_0001.ts\n#EXTINF:6.680000,\n_320p_0002.ts\n#EXTINF:2.600000,\n_320p_0003.ts\n#EXT-X-ENDLIST\n"
}
}
}
],
"total_duration": 80
}
I have created the respective model class as This is the root model
@JsonIgnoreProperties(ignoreUnknown = true)
public class AdsResponse {
@JsonProperty("ads")
List<Ad> ads;
@JsonProperty("total_duration")
long totalDuration;
}
Then the ads model
public class Ad {
Map<String,AdInfo> ad;}
Then the AdInfo model
public class AdInfo {
@JsonProperty("m3u8_text")
AdManifest adManifest;
int duration;
@JsonProperty("ad_id")
String adId;}
Then the manifest model
public class AdManifest {
@JsonProperty("_1280p")
String _1280p;
@JsonProperty("_320p")
String _320p;}
When I try to parse this using below code
AdsResponse response = new ObjectMapper().readValue(
res,
AdsResponse.class);
I get the empy ad object
AdsResponse{ads=[Ad{ad=null}, Ad{ad=null}, totalDuration=80}
What is wrong here?
CodePudding user response:
You don't actually need the Ad
class, it's just a Map<>
. AdResponse
can look like this:
public class AdsResponse {
@JsonProperty("ads")
List<Map<String, AdInfo>> ads;
@JsonProperty("total_duration")
long totalDuration;
If the keys in the map were predictable, you could make them properties on the Ad
class and then Jackson would map them properly. But since they're not (they look like some kind of ID), mapping them to a Map<>
is probably the best option.
As an alternative, if you want or need to have the Ad
objects, you can map them like this:
public class Ad {
Map<String, AdInfo> adInfo = new HashMap<>();
@JsonAnySetter
public void setAds(String key, AdInfo value) {
adInfo.put(key, value);
}
}
With that, and AdResponse
defined the way you have it in the question, you'll get populated Ad
instances, each of which has a Map<>
with only 1 key/value pair. For an even simpler (and probably more sensible model, you can eliminate the Map
if there is only ever 1 key in an Ad
, like this:
public class Ad {
private AdInfo adInfo;
@JsonAnySetter
public void setAdInfo(String ignored, AdInfo value) {
this.adInfo = value;
}
}