2012-05-08 10 views
49

Sto eseguendo l'autenticazione http di base con l'oggetto HttpURLConnection in Java.Parse JSON dall'oggetto HttpURLConnection

 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; 
     } 

mi aspetto un oggetto JSON, o dati stringa nel formato di un oggetto valido JSON o HTML con un semplice testo che è JSON valido. Come posso accedervi dal HttpURLConnection dopo che ha restituito una risposta?

+2

Si noti che tutti i codici di stato HTTP 2xx indicano successo. – Fred

risposta

95

È possibile ottenere dati grezzi usando sotto metodo. A proposito, questo modello è per Java 6. Se si utilizza Java 7 o versione successiva, si prega di prendere in considerazione 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; 
} 

E quindi è possibile utilizzare stringa restituita con Google Gson per mappare JSON per oggetto della classe specificato, in questo modo:

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

C'è un campione di classe 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; 
    } 
} 

JSON restituito da http://localhost/authmanager.php deve essere simile al seguente:

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

saluti

+1

Posso chiederti, dove chiudi la connessione 'c'? –

+0

Originariamente l'ho scritto in modo java 7 con try-with-resources, ma qualcuno ha deciso di mantenere java 6, quindi la chiusura della connessione è stata ignorata. Ma sì, la connessione deve essere chiusa. Lo modificherò più tardi, grazie. – kbec

+0

@kbec Ancora non vedo dove si chiude la connessione. Potresti per favore aggiungere questo alla tua risposta? – confile

9

Definire la seguente funzione (non la mia, non so dove l'ho trovato molto tempo fa):

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(); 

}

Poi:

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

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

'convertStreamToString' non notifica al codice chiamante che la stringa è incompleta se una connessione viene persa a metà trasferimento. In generale, è meglio lasciar emergere le eccezioni. –

2

La stringa JSON sarà solo il corpo della risposta che torni dall'URL che hai chiamato. Quindi aggiungi questo codice

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

Ciò consentirà di vedere il JSON che viene restituito alla console. L'unico pezzo mancante che hai è usare una libreria JSON per leggere quei dati e fornirti una rappresentazione Java.

Here's an example using JSON-LIB

+0

Il buffer di input non viene chiuso se c'è un'eccezione nella lettura dell'input. –

2

Inoltre, se si desidera analizzare il vostro oggetto nel caso di errore HTTP (400-5 codici **), È possibile utilizzare il seguente codice: (basta sostituire 'getInputStream' con '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

Questa funzione verrà utilizzata per ottenere i dati dall'URL sotto forma di oggetto 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); 
} 

Sopra funzione viene chiamata qui e riceviamo una forma String del JSON utilizzando la libreria Class.And Apache in seguito alle dichiarazioni che cerchiamo di rendere semplice POJO fuori dalla JSON che abbiamo ricevuto.

String jsonString  =  
EntityUtils.toString(getResponse("http://echo.jsontest.com/title/ipsum/content/ blah","Your_auth_if_you_need_one").getEntity(), "UTF-8"); 
final GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(JsonJavaModel .class, new CustomJsonDeserialiser()); 
final Gson gson = gsonBuilder.create(); 
JsonElement json = new JsonParser().parse(jsonString); 
JsonJavaModel pojoModel = gson.fromJson(
        jsonElementForJavaObject, JsonJavaModel.class); 

Questa è una semplice classe di modello java per incomming json. classe pubblica JsonJavaModel { Contenuto di stringhe; Titolo stringa; } Questa è una deserialiser personalizzato:

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; 
} 

: Biblioteca GSON e org.apache.http.util.EntityUtils;