2013-05-10 100 views
0

我有一段示例代碼來請求來自網站的數據,而我得到的響應原來是亂碼。JSON響應並將其轉換爲JSON對象

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 


public class NetClientGet 
{ 

public static void main(String[] args) 
{ 

    try 
    { 

     URL url = new URL("http://fids.changiairport.com/webfids/fidsp/get_flightinfo_cache.php?d=0&type=pa&lang=en"); 

     HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
     conn.setRequestMethod("GET"); 
     conn.setRequestProperty("Accept", "application/json"); 

     if (conn.getResponseCode() != 200) 
     { 
      throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode()); 
     } 

     System.out.println("the connection content type : " + conn.getContentType()); 

     // convert the input stream to JSON 
     BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); 

     String output; 
     System.out.println("Output from Server .... \n"); 
     while ((output = br.readLine()) != null) 
     { 
      System.out.println(output); 
     } 
     conn.disconnect(); 
    } catch (MalformedURLException e) 
    { 
     e.printStackTrace(); 
    } catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

}

如何InputStream的轉換成可讀的JSON對象。發現了幾個問題,但他們已經有了答案並試圖解析。

+0

是否要conn.getOutputStream()來代替? – softwarebear 2013-05-10 09:13:32

回答

4

您的代碼的第一個問題是服務器正在壓縮您未處理的響應數據。你可以很容易地通過瀏覽器獲取數據來看,在響應報頭驗證這一點:

HTTP/1.1 200 OK
日期:星期五,2013 GMT 16時03分45秒
服務器5月10日:阿帕奇/2.2.17(UNIX)PHP/5.3.6
X供電-通過:PHP/5.3.6
有所不同:接受編碼
內容編碼:gzip
保持活動:超時= 5 ,max = 100
連接:Keep-Alive
傳輸編碼:分塊
內容類型:應用程序/ JSON

這就是爲什麼你的輸出看起來像 '胡言亂語'。要解決這個問題,只需在URL連接輸出流的頂部鏈接一個GZIPInputStream即可。

// convert the input stream to JSON 
BufferedReader br; 
if ("gzip".equalsIgnoreCase(conn.getContentEncoding())) { 
    br = new BufferedReader(new InputStreamReader(
      (new GZIPInputStream(conn.getInputStream())))); 
} else { 
    br = new BufferedReader(new InputStreamReader(
      (conn.getInputStream()))); 
} 

的第二個問題是,返回的數據實際上是JSONP格式(JSON包裹在一個回調函數,像callback_function_name(JSON);)。您需要在解析之前解壓縮它:

// Retrieve data from server 
String output = null; 
final StringBuffer buffer = new StringBuffer(16384); 
while ((output = br.readLine()) != null) { 
    buffer.append(output); 
} 
conn.disconnect(); 

// Extract JSON from the JSONP envelope 
String jsonp = buffer.toString(); 
String json = jsonp.substring(jsonp.indexOf("(") + 1, 
     jsonp.lastIndexOf(")")); 
System.out.println("Output from server"); 
System.out.println(json); 

因此,現在您已從服務器獲得所需的數據。此時,您可以使用任何標準的JSON庫來解析它。例如,使用GSON

final JSONElement element = new JSONParser().parse(json); 
+0

非常感謝,不知道GZIP編碼。如果可能的話+ 100,但我只能接受你的答案。再次感謝 – jonleech 2013-05-13 00:51:29