2012-07-26 72 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