I'm using Google Books Api
to show list of books, but when I try to get thumbnail url from imageLinks
JSONObject
, then the JSONException
says that there's no value for imageLinks
even though the value exists in this object.
I tried methods like JSONObject.isNull()
or optString()
instead of getString()
, but it still doesn't give me any value.
Here's the URL that I'm trying to get data from: https://www.googleapis.com/books/v1/volumes?q=android
Here's the code:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener < JSONObject > () {
@Override
public void onResponse(JSONObject response) {
if (response != null) {
try {
JSONArray jsonItemsArray = response.getJSONArray("items");
for (int i = 0; i < jsonItemsArray.length(); i++) {
String thumbnailUrl = "";
String title = "";
JSONObject item = jsonItemsArray.getJSONObject(i);
JSONObject volumeInfo = item.getJSONObject("volumeInfo");
JSONObject thumbnailUrlObject = volumeInfo.getJSONObject("imageLinks");
if (!thumbnailUrlObject.isNull("thumbnail")) {
thumbnailUrl = thumbnailUrlObject.getString("thumbnail");
}
title = volumeInfo.getString("title");
bookList.add(new Book(title, thumbnailUrl));
booksAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
And this is a piece of the JSON response:
"kind": "books#volumes",
"totalItems": 500,
"items": [
{
"kind": "books#volume",
"id": "JUVjAgAAQBAJ",
"etag": "kbnCYPNPKq4",
"selfLink": "https://www.googleapis.com/books/v1/volumes/JUVjAgAAQBAJ",
"volumeInfo": {
"title": "Android. Podstawy tworzenia aplikacji",
"authors": [
"Andrzej Stasiewicz"
],
"publisher": "Helion",
"publishedDate": "2013-11-10",
"description": "Na szczęście dostępna jest już książka Android.",
"industryIdentifiers": [
{
"type": "ISBN_13",
"identifier": "9788324688418"
},
{
"type": "ISBN_10",
"identifier": "8324688412"
}
],
"readingModes": {
"text": true,
"image": true
},
"pageCount": 216,
"printType": "BOOK",
"categories": [
"Computers"
],
"averageRating": 4.0,
"ratingsCount": 1,
"maturityRating": "NOT_MATURE",
"allowAnonLogging": true,
"contentVersion": "1.4.4.0.preview.3",
"imageLinks": {
"smallThumbnail": "http://books.google.com/books/content?id=JUVjAgAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://books.google.com/books/content?id=JUVjAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
}
And I wonder why does volumeInfo.getJSONObject("imageLinks")
give me JSONException
with No value for, even though the imageLinks
has value.
Not every volumeInfo
node has imageLinks
node, so you need to check whether given node exists using node.has
method or node.opt*
method and checking if result is not null
. Below you can find safe way hot to get thumbnail
node:
JSONObject thumbnailUrlObject = volumeInfo.optJSONObject("imageLinks");
if (thumbnailUrlObject != null && thumbnailUrlObject.has("thumbnail")) {
thumbnailUrl = thumbnailUrlObject.getString("thumbnail");
}
Simple console app which shows how it works:
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.nio.file.Files;
public class OrgJsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
String json = String.join("", Files.readAllLines(jsonFile.toPath()));
JSONObject response = new JSONObject(json);
// get items
JSONArray jsonItemsArray = response.getJSONArray("items");
for (int i = 0; i < jsonItemsArray.length(); i++) {
String thumbnailUrl = "";
JSONObject item = jsonItemsArray.getJSONObject(i);
JSONObject volumeInfo = item.getJSONObject("volumeInfo");
JSONObject thumbnailUrlObject = volumeInfo.optJSONObject("imageLinks");
if (thumbnailUrlObject != null && thumbnailUrlObject.has("thumbnail")) {
thumbnailUrl = thumbnailUrlObject.getString("thumbnail");
}
String title = volumeInfo.getString("title");
System.out.println("title => " + title);
System.out.println("thumbnail => " + thumbnailUrl);
}
}
}
Above code for your JSON
payload prints:
title => Android Aplikacje wielowątkowe techniki przetwarzania
thumbnail =>
title => Android. Receptury
thumbnail => http://books.google.com/books/content?id=pZ5iAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Android. Podstawy tworzenia aplikacji
thumbnail => http://books.google.com/books/content?id=JUVjAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Optymalizacja wydajności aplikacji na Android
thumbnail => http://books.google.com/books/content?id=WJ1iAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Inteligentny dom. Automatyzacja mieszkania za pomocą platformy Arduino, systemu Android i zwykłego komputera
thumbnail => http://books.google.com/books/content?id=koiKAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Android UI. Podręcznik dla projektantów. Smashing Magazine
thumbnail => http://books.google.com/books/content?id=HEJjAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Android. Programowanie gier na tablety
thumbnail => http://books.google.com/books/content?id=7J1iAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Profesjonalne tworzenie gier internetowych dla systemu Android w językach HTML5, CSS3 i JavaScript
thumbnail => http://books.google.com/books/content?id=vlNjAgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Beginning Android 2
thumbnail => http://books.google.com/books/content?id=2XeNswkT_2YC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
title => Pro Android 2
thumbnail => http://books.google.com/books/content?id=Bam8K5SIiTkC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api