I am trying to extract title, videoId, and description data of all the videos I got from using YT Data API. I was able to return the data in what looks like JSON format (but it is actually LinkedHashMap when I check with getClass()
) in Postman and Chrome browser, but was unable to extract the value from specific keys I have mentioned above.
I tried:
System.out.println((rest.getForObject(url, Object.class, params)).get("items"));
It asks me to cast to JSONObject
Overall, I need to extract the data and convert into xml before sending it over to ActiveMQ
Edit: Format I get in Postman/Chrome browser
{
"kind": "youtube#searchListResponse",
"etag": "3LV4enCWAzOaiqJb_cMIUVklXJY",
"nextPageToken": "CAUQAA",
"regionCode": "CA",
"pageInfo": {
"totalResults": 478712,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "gt6x7J2XpzU8Mpb3yv9_HmNTzWY",
"id": {
"kind": "youtube#video",
"videoId": "I_ZK0t9-llo"
},
"snippet": {
"publishedAt": "2021-03-01T18:15:13Z",
"channelId": "UC2WHjPDvbE6O328n17ZGcfg",
"title": "Stack Overflow is full of idiots.",
"description": "The Stack Overflow culture needs to be fixed. The overall gatekeeping & elitism in computer science & programming - as a whole ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "ForrestKnight",
"liveBroadcastContent": "none",
"publishTime": "2021-03-01T18:15:13Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "RwmGP1qMzUCzK6oV82s0NUEOETw",
"id": {
"kind": "youtube#video",
"videoId": "sMIslcynm0Q"
},
"snippet": {
"publishedAt": "2021-03-07T16:00:13Z",
"channelId": "UCXwjZTvpFiBl93ACCUh1NXQ",
"title": "How To Use Stack Overflow (no, ForrestKnight, it's not full of idiots)",
"description": "Hey everyone, I can't believe I have to make this video. Unfortunately ForrestKnight recently made a video saying Stack Overflow ...",
"thumbnails": {
...
Edit2: I tried
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
JSONArray array = jsonObject.getJSONArray("items" );
for(int i=0;i<array.length();i ){
JSONObject snippet =array.getJSONObject(i);
System.out.println(snippet.getJSONObject("snippet").get("title"));
}
JSONObject["items"] not found.
Edit3: I also tried without Edit2 and just
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
System.out.println(jsonObject);
No error and I was about to fetch data shown in Postman. But in console printed {}
, meaning I might not have gotten the data and won't be able to extract.
I tried extracting using .get System.out.println(jsonObject.get("items"));
and I got the same error JSONObject["items"] not found.
Seems like it could be a format error, again it looks like json already and to use .get, I placed it inside jsonObject but found nothing
Edit4: I can confirm the data I get back is Json (like it says on the doc) using
try {
new JSONObject(rest.getForObject(url, Object.class, params));
} catch (JSONException ex) {
// edited, to include @Arthur's comment
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(rest.getForObject(url, Object.class, params));
} catch (JSONException ex1) {
return false;
}
}
return true;
Returned true
Edit5: Seems like the keys is null after trying
String[] keys = JSONObject.getNames(jsonObject);
// iterate over them
for (String key1 : keys) {
// retrieve the values
Object value = jsonObject.get(key1);
// if you just have strings:
String value1 = (String) jsonObject.get(key1);
System.out.println(value);
System.out.println(value1);
}
Cannot read the array length because "keys" is null
CodePudding user response:
The RestTemplate
delegates to the underlying Jackson to deserialize the JSON string to a java object .If you get the HTTP response as a generic object type , it will deserialize it into a Map
.
You can simply create a POJO with the structure that is the same as the expected JSON response, and then use the Jackson
annotations to configure how to deserialize the JSON into this POJO , and get the HTTP response as this POJO class.
Something like :
public class Result {
@JsonProperty("items")
private List<Item> items = new ArrayList<>();
}
public class Item {
@JsonProperty("kind")
private String kind;
@JsonProperty("etag")
private String etag;
@JsonProperty("snippet")
private List<Snippet> snippets = new ArrayList<>();
}
public class Snippet {
@JsonProperty("channelId")
private String channelId;
@JsonProperty("title")
private String title;
}
Then use the following to get the response :
Result result = rest.getForObject(url, Result.class, params);
Once you get the Result POJO , use the favourite library to serialize it into XML.
P.S I just show you the ideas. You have to fine tune the POJO structure