2012-05-08 74 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;