2012-05-08 25 views
49

Estoy haciendo http auth básica con el objeto HttpURLConnection en Java.Parse JSON del objeto 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; 
     } 

Estoy esperando un objeto JSON, o datos de cadena en el formato de un objeto válido JSON o HTML con un simple texto sin formato que es JSON válida. ¿Cómo puedo acceder desde el HttpURLConnection después de que devuelve una respuesta?

+2

Tenga en cuenta que todos los códigos de estado HTTP 2xx indican éxito. – Fred

Respuesta

95

Puede obtener datos sin procesar mediante el siguiente método. Por cierto, este patrón es para Java 6. Si está utilizando Java 7 o posterior, considere 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; 
} 

Y entonces usted puede utilizar cadena devuelta con Google Gson para mapear JSON al objeto de la clase especificada, así:

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

Hay una muestra de la clase 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 devuelto por http://localhost/authmanager.php debe tener este aspecto:

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

Saludos

+1

¿Puedo preguntarle dónde cierra la conexión 'c'? –

+0

Originalmente escribí esto en modo java 7 con try-with-resources, pero alguien decidió mantener java 6, por lo que el cierre de la conexión se ignoró finalmente. Pero sí, la conexión debe estar cerrada. Voy a editar esto más tarde, gracias. – kbec

+0

@kbec Aún no veo dónde se cierra la conexión. ¿Podría agregar esto a su respuesta? – confile

9

Definir la siguiente función (no la mía, no sabe dónde lo encontré hace mucho tiempo):

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

}

continuación:

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

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

'convertStreamToString' no notifica al código de llamada que la cadena está incompleta si se pierde una conexión a mitad de la transferencia. En general, es mejor dejar que las excepciones salgan a relucir. –

2

La cadena JSON sólo será el cuerpo de la respuesta que obtiene de la URL que ha llamado. Así que agregue este código

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

Eso le permitirá ver que el JSON se devuelve a la consola. La única pieza faltante que tienes es utilizar una biblioteca JSON para leer esos datos y proporcionarte una representación de Java.

Here's an example using JSON-LIB

+0

El búfer de entrada no se cierra si hay una excepción al leer la entrada. –

2

Además, si desea analizar su objeto en caso de error HTTP (400-5 códigos **), Usted puede utilizar el código siguiente: (basta con sustituir '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

Esta función se utilizará para obtener los datos de url en forma de objeto 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); 
} 

Por encima de la función se llama aquí y recibimos una forma de cadena del JSON utilizando el Class.And biblioteca de Apache en el seguimiento de las declaraciones que tratamos de hacer POJO sencilla fuera del JSON que recibimos.

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

Esta es una clase de modelo Java simple para incoming json. clase pública JsonJavaModel { Contenido de cadena; Título de cadena; } Esta es una deserialiser personalizado:

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

Incluir biblioteca y org.apache.http.util.EntityUtils Gson;