2012-07-26 69 views
1

我刚刚开始忙于一些网络编程,并试图从音乐网站的API中检索某些音乐艺术家的信息。我正在使用JSON.simple工具包发现here.解析并从JSON中检索信息 - JSONObject与JSONArray?

这是我的代码。两类,一类是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末的print语句给了我这样的:

{"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)); 

回答

0

原因很简单,你的JSON的输入数据的结构:它是只用results属性,它的值是一个数组,这个数组包含你真正想要的数据JSON对象。

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

这似乎是一个相当平凡的对象,只有一个属性,但这在JSON响应中并不少见,实际上在任何类型的网络通信中都是如此:您实际需要的结果包含在一个对象中,提供与实际结果数据相关的元信息的附加属性。

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

您可以通过丢弃read方法中的外部对象来解析响应的结果 - readJsonFromUrl方法的结果 - 数组,但有时候会有更多的对象包含您可能想保留的对象,例如一些与结果列表一起出现的头部数据/元信息,这可能会影响您使用数据的方式。

+0

啊,我明白了。非常感谢!所以我得到我检索的数据是一个JSON对象(用大括号表示,我假设),其结果属性是JSONArray。 我正确地说,直接返回JSON对象和JSONArrays的JSON响应有所不同吗?像我的情况那样,返回一个JSONObject,对于API来说更频繁的事情呢? – 2012-07-26 07:14:47

+0

是的,通常API会将JSON对象作为外部包装返回,这允许包括头部/元数据信息以及实际结果。作为一个简单的例子:假设API限制了可以在一次呼叫中返回的艺术家的数量,例如50.与'results'一起,它还会在对象中有一个'hasMore'字段或者一个'remainingCount'字段,以便让调用者知道更多数据何时可用。 – pb2q 2012-07-26 07:20:57

+0

非常好,再次感谢! – 2012-07-26 07:24:30