I’m working on a Java application that needs to fetch album artwork from Spotify’s web API. When I make a request to their search endpoint, I get back JSON data that contains image information with different sizes like this:
"height" : 64,
"url" : "https://i.scdn.co/image/example123456789abcdef",
"width" : 64
I want to parse this JSON response and extract the image URL so I can display the album cover in my app. Here’s my current method that handles the API call:
public void fetchAlbumArt(String albumName) {
String apiEndpoint = "https://api.spotify.com/v1/search?q=" + formatQuery(albumName) + "&type=album";
java.net.URL apiUrl = null;
try {
BufferedImage albumImage = null;
apiUrl = new java.net.URL(apiEndpoint);
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
InputStream stream = null;
try {
stream = apiUrl.openStream();
} catch (IOException ex) {
ex.printStackTrace();
}
java.io.BufferedReader jsonReader = null;
try {
jsonReader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
String imageUrl;
try {
imageUrl = jsonReader.readLine(); // need to extract 64x64 image URL here
} catch (IOException ex) {
ex.printStackTrace();
}
try {
URL coverUrl = new URL(imageUrl);
albumImage = ImageIO.read(coverUrl);
ImageIcon coverIcon = new ImageIcon(albumImage);
albumLabel.setIcon(coverIcon);
} catch (IOException ex) {
ex.printStackTrace();
}
}
The problem is that readLine() just gets the raw JSON response. How can I properly parse the JSON to extract just the image URL and assign it to my imageUrl variable?
You can’t parse JSON with basic string operations - you need a proper JSON library. I’d go with Jackson or Gson. Jackson lets you either create POJOs to map the structure or use JsonNode for flexible parsing. Here’s what I used on a similar project:
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonReader);
JsonNode albums = root.path("albums").path("items");
if (albums.isArray() && albums.size() > 0) {
JsonNode images = albums.get(0).path("images");
for (JsonNode image : images) {
if (image.path("height").asInt() == 64) {
imageUrl = image.path("url").asText();
break;
}
}
}
Make sure to add Jackson as a dependency. You’ll probably want error handling too for when there’s no 64x64 image in the response.
Had the same issue. Your approach has a bigger problem than just JSON parsing - you’re using readLine() for the entire response but not handling HTTP auth headers properly. Spotify needs authentication. Once I fixed that, I used the minimal-json library and it worked great. Read the full response first, then parse it. Pro tip: Spotify doesn’t always return images in the same order, so don’t hardcode the 64x64 search. I just grab the smallest available image as backup. Also handle empty album arrays - happens way more than you’d think with weird album names.
Your issue stems from processing JSON as if it were plain text. The readLine() method retrieves only the first line of response, but the JSON from Spotify is multi-line. I faced a similar challenge and found that using Gson simplifies the parsing considerably.
Instead of reading just one line, read the complete response into a string. Following this, Gson can handle the parsing effectively. Here’s an example:
Gson gson = new Gson();
JsonObject jsonResponse = gson.fromJson(jsonReader, JsonObject.class);
JsonArray albums = jsonResponse.getAsJsonObject("albums").getAsJsonArray("items");
if (albums.size() > 0) {
JsonArray images = albums.get(0).getAsJsonObject().getAsJsonArray("images");
for (JsonElement img : images) {
JsonObject imageObj = img.getAsJsonObject();
if (imageObj.get("height").getAsInt() == 64) {
imageUrl = imageObj.get("url").getAsString();
break;
}
}
}
Ensure you add the Gson library as your dependency. Also, keep in mind that not all albums will contain a 64x64 image; consider implementing a fallback mechanism for other dimensions.
Just use org.json - way simpler than Jackson or Gson for basic stuff. Try this: JSONObject json = new JSONObject(fullResponse); String imageUrl = json.getJSONObject("albums").getJSONArray("items").getJSONObject(0).getJSONArray("images").getJSONObject(0).getString("url"); This assumes there’s always an image though.