2012-05-08 68 views
49

我正在用Java中的HttpURLConnection對象進行基本的http驗證。從HttpURLConnection對象解析JSON

 URL urlUse = new URL(url); 
     HttpURLConnection conn = null; 
     conn = (HttpURLConnection) urlUse.openConnection(); 
     conn.setRequestMethod("GET"); 
     conn.setRequestProperty("Content-length", "0"); 
     conn.setUseCaches(false); 
     conn.setAllowUserInteraction(false); 
     conn.setConnectTimeout(timeout); 
     conn.setReadTimeout(timeout); 
     conn.connect(); 

     if(conn.getResponseCode()==201 || conn.getResponseCode()==200) 
     { 
      success = true; 
     } 

我期待一個JSON對象,或在一個有效的JSON對象或HTML與簡單的純文本是有效的JSON格式的字符串數據。如何在返回響應後從HttpURLConnection訪問?

+2

請注意,所有2xx HTTP狀態碼都表示成功。 – Fred

回答

95

您可以使用以下方法來獲取原始數據。順便說一下,這種模式適用於Java 6.如果您使用Java 7或更新版本,請考慮try-with-resources pattern

public String getJSON(String url, int timeout) { 
    HttpURLConnection c = null; 
    try { 
     URL u = new URL(url); 
     c = (HttpURLConnection) u.openConnection(); 
     c.setRequestMethod("GET"); 
     c.setRequestProperty("Content-length", "0"); 
     c.setUseCaches(false); 
     c.setAllowUserInteraction(false); 
     c.setConnectTimeout(timeout); 
     c.setReadTimeout(timeout); 
     c.connect(); 
     int status = c.getResponseCode(); 

     switch (status) { 
      case 200: 
      case 201: 
       BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); 
       StringBuilder sb = new StringBuilder(); 
       String line; 
       while ((line = br.readLine()) != null) { 
        sb.append(line+"\n"); 
       } 
       br.close(); 
       return sb.toString(); 
     } 

    } catch (MalformedURLException ex) { 
     Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) { 
     Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
    } finally { 
     if (c != null) { 
      try { 
       c.disconnect(); 
      } catch (Exception ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 
    return null; 
} 

然後你就可以使用返回的字符串與Google Gson映射JSON到對象指定類的,就像這樣:

String data = getJSON("http://localhost/authmanager.php"); 
AuthMsg msg = new Gson().fromJson(data, AuthMsg.class); 
System.out.println(msg); 

有AuthMsg類的一個示例:

public class AuthMsg { 
    private int code; 
    private String message; 

    public int getCode() { 
     return code; 
    } 
    public void setCode(int code) { 
     this.code = code; 
    } 

    public String getMessage() { 
     return message; 
    } 
    public void setMessage(String message) { 
     this.message = message; 
    } 
} 

http://localhost/authmanager.php返回的JSON必須如下所示:

{"code":1,"message":"Logged in"} 

問候

+1

我可以問你,關閉連接'c'嗎? –

+0

最初我以java 7的方式寫了這個與try-with-resources的方式,但有人決定保留java 6,所以最後忽略連接關閉。但是,是的,連接必須關閉。我稍後再編輯,謝謝。 – kbec

+0

@kbec我仍然沒有看到您關閉連接的位置。你能否把這個添加到你的答案? – confile

9

定義以下功能(不是我的,不知道在哪裏,我發現它很久以前):

private static String convertStreamToString(InputStream is) { 

BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
StringBuilder sb = new StringBuilder(); 

String line = null; 
try { 
    while ((line = reader.readLine()) != null) { 
     sb.append(line + "\n"); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} finally { 
    try { 
     is.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
return sb.toString(); 

}

然後:

String jsonReply; 
if(conn.getResponseCode()==201 || conn.getResponseCode()==200) 
    { 
     success = true; 
     InputStream response = conn.getInputStream(); 
     jsonReply = convertStreamToString(response); 

     // Do JSON handling here.... 
    } 
+0

如果連接在傳輸過程中丟失,'convertStreamToString'不會通知調用代碼該字符串不完整。一般來說,最好讓例外冒出來。 –

2

JSON字符串只會是您從所調用的網址獲取的回覆正文。因此,添加此代碼

... 
BufferedReader in = new BufferedReader(new InputStreamReader(
          conn.getInputStream())); 
String inputLine; 
while ((inputLine = in.readLine()) != null) 
    System.out.println(inputLine); 
in.close(); 

這將允許您看到JSON被返回到控制檯。您唯一缺少的部分是使用JSON庫來讀取數據併爲您提供Java表示。

Here's an example using JSON-LIB

+0

如果讀取輸入有異常,輸入緩衝區不會關閉。 –

2

此外,如果你希望你的分析對象HTTP錯誤(400-5 **碼), 您可以使用下面的代碼的情況下:(只需更換「的getInputStream」與「getErrorStream」 :

BufferedReader rd = new BufferedReader(
      new InputStreamReader(conn.getErrorStream())); 
    StringBuilder sb = new StringBuilder(); 
    String line; 
    while ((line = rd.readLine()) != null) { 
     sb.append(line); 
    } 
    rd.close(); 
    return sb.toString(); 
1

該函數將用於從url中以HttpResponse對象的形式獲取數據。

public HttpResponse getRespose(String url, String your_auth_code){ 
HttpClient client = new DefaultHttpClient(); 
HttpPost postForGetMethod = new HttpPost(url); 
postForGetMethod.addHeader("Content-type", "Application/JSON"); 
postForGetMethod.addHeader("Authorization", your_auth_code); 
return client.execute(postForGetMethod); 
} 

以上功能在這裏打了個電話,我們收到使用Apache庫Class.And在下面的語句,我們儘量讓簡單的POJO了,我們收到的JSON的JSON的字符串形式。

​​

這是一個簡單的java模型類,用於包含json。公共類JsonJavaModel { 字符串內容; 字符串標題; } 這是一個自定義解串器:

public class CustomJsonDeserialiserimplements JsonDeserializer<JsonJavaModel>   { 

@Override 
public JsonJavaModel deserialize(JsonElement json, Type type, 
           JsonDeserializationContext arg2) throws JsonParseException { 
    final JsonJavaModel jsonJavaModel= new JsonJavaModel(); 
    JsonObject object = json.getAsJsonObject(); 

    try { 
    jsonJavaModel.content = object.get("Content").getAsString() 
    jsonJavaModel.title = object.get("Title").getAsString() 

    } catch (Exception e) { 

     e.printStackTrace(); 
    } 
    return jsonJavaModel; 
} 

包括GSON庫和org.apache.http.util.EntityUtils;