从Java中的JSON解析和检索信息——JSONObject与JSONArray



我刚开始处理一些网络编程,并试图从音乐网站的API中检索某些音乐艺术家的信息。我使用的是这里的JSON.simple工具包。

这是我的密码。两个类别,一个是JSONReader:

import org.json.simple.*;
import org.json.simple.parser.*;
import java.net.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
public class JSONReader {
private static String readAll(Reader rd) throws IOException {
    StringBuilder sb = new StringBuilder();
    int cp;
    while ((cp = rd.read()) != -1) {
      sb.append((char) cp);
    }
    return sb.toString();
  }
public static JSONObject readJsonFromUrl(String url) throws IOException, ParseException {
    JSONParser parser = new JSONParser();
    InputStream is = new URL(url).openStream();
    try {
      BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
      String jsonText = readAll(rd);
      Object obj = parser.parse(jsonText);
      JSONObject result = (JSONObject) obj;
      return result;
    } finally {
      is.close();
    }
  }
}

好的,这是我的Main课程:

public class Main {
public static void main(String[] args) throws Exception {
    System.out.println("Starting execution of program...");
    String searchQuery = args[0];
    JSONReader reader = new JSONReader();
    System.out.println("Beginning HTTP request...");
    String baseURL = "http://api.discogs.com/database/search?q=" + searchQuery + "&type=artist";
    JSONObject json = reader.readJsonFromUrl(baseURL);
    System.out.println(json);

main末尾的打印语句给出了以下内容:

{"results":[{"id":22898,"title":"Tool","type":"artist","resource_url":"http://api.discogs.com/artists/22898","uri":"/artist/Tool","thumb":null},{"id":5481,"title":"DJ Tool","type":"artist","resource_url":"http://api.discogs.com/artists/5481","uri":"/artist/DJ+Tool","thumb":null},{"id":186087,"title":"Tool (3)","type":"artist","resource_url":"http://api.discogs.com/artists/186087","uri":"/artist/Tool+%283%29","thumb":null},{"id":108078,"title":"Rave Tool","type":"artist","resource_url":"http://api.discogs.com/artists

大约还有十几位艺术家,他们都是以大括号和逗号区分的。

所以我通过做"得到"results

System.out.println(json.get("results"));

最终得到:

[{"id":22898,"title":"Tool","type":"artist","resource_url":"http://api.discogs.com/artists/22898","uri":"/artist/Tool","thumb":null},{"id":5481,"title":"DJ Tool", ... ]

问题是,我希望能够从搜索结果中提取出十几位左右的艺术家。

我将上面的转换为JSONArray,如下所示,然后我可以"获取"搜索结果的索引。在这篇长文之后,我的问题是:为什么会这样?从本质上讲,如果JSONObject需要是一个JSONArray来访问结果索引,那么它的首要意义是什么?另外,我不能将解析jsonText的结果直接设置为JSONArray是有原因的吗?当我尝试将readJsonFromUrl方法中的所有"JSONObject"更改为JSONArrays时,会出现一个错误,说它无法将JSONObject强制转换为JSONArray。为什么会这样?

JSONArray json1 = (JSONArray) reader.readJsonFromUrl(baseURL).get("results");
System.out.println(json1);
System.out.println(json1.get(0));

原因只是JSON输入数据的结构:它是一个只有results属性的JSON对象,其值是一个数组,该数组包含您实际想要的数据。

由于您有一个对象,其单个属性是包含所需数据的数组,因此必须解析整个对象才能获取数组。

这似乎是一个只有单个属性的微不足道的对象,但这在JSON响应中并不罕见,在任何类型的网络通信中都是如此:您实际想要的结果被包裹在一个对象中,该对象有时会包含额外的属性,这些属性提供与实际结果数据相关的元信息。

将这个外部对象视为包含结果的信封

您可以通过在读取方法中丢弃外部对象,使解析响应的结果(readJsonFromUrl方法的结果)成为数组,但有时您可能希望保留更多的包含对象,例如结果列表中附带的一些标头数据/元信息,这可能会影响数据的使用方式。

最新更新