2012-02-03 43 views
17

Estoy haciendo un rastreador, y necesito obtener los datos de la transmisión independientemente de si es 200 o no. CURL lo está haciendo, así como cualquier navegador estándar.URLConnection no me permite acceder a los datos sobre errores Http (404,500, etc.)

Lo siguiente no obtendrá realmente el contenido de la solicitud, aunque hay algunos, se lanza una excepción con el código de estado de error http. Quiero la salida independientemente, ¿hay alguna manera? Prefiero usar esta biblioteca ya que de hecho hará conexiones persistentes, lo cual es perfecto para el tipo de rastreo que estoy haciendo.

package test; 

import java.net.*; 
import java.io.*; 

public class Test { 

    public static void main(String[] args) { 

     try { 

      URL url = new URL("http://github.com/XXXXXXXXXXXXXX"); 
      URLConnection connection = url.openConnection(); 

      DataInputStream inStream = new DataInputStream(connection.getInputStream()); 
      String inputLine; 

      while ((inputLine = inStream.readLine()) != null) { 
       System.out.println(inputLine); 
      } 
      inStream.close(); 
     } catch (MalformedURLException me) { 
      System.err.println("MalformedURLException: " + me); 
     } catch (IOException ioe) { 
      System.err.println("IOException: " + ioe); 
     } 
    } 
} 

funcionado, gracias: Esto es lo que me ocurrió con - al igual que una prueba aproximada del concepto:

import java.net.*; 
import java.io.*; 

public class Test { 

    public static void main(String[] args) { 
//InputStream error = ((HttpURLConnection) connection).getErrorStream(); 

     URL url = null; 
     URLConnection connection = null; 
     String inputLine = ""; 

     try { 

      url = new URL("http://verelo.com/asdfrwdfgdg"); 
      connection = url.openConnection(); 

      DataInputStream inStream = new DataInputStream(connection.getInputStream()); 

      while ((inputLine = inStream.readLine()) != null) { 
       System.out.println(inputLine); 
      } 
      inStream.close(); 
     } catch (MalformedURLException me) { 
      System.err.println("MalformedURLException: " + me); 
     } catch (IOException ioe) { 
      System.err.println("IOException: " + ioe); 

      InputStream error = ((HttpURLConnection) connection).getErrorStream(); 

      try { 
       int data = error.read(); 
       while (data != -1) { 
        //do something with data... 
        //System.out.println(data); 
        inputLine = inputLine + (char)data; 
        data = error.read(); 
        //inputLine = inputLine + (char)data; 
       } 
       error.close(); 
      } catch (Exception ex) { 
       try { 
        if (error != null) { 
         error.close(); 
        } 
       } catch (Exception e) { 

       } 
      } 
     } 

     System.out.println(inputLine); 
    } 
} 

Respuesta

37

simple:

URLConnection connection = url.openConnection(); 
InputStream is = connection.getInputStream(); 
if (connection instanceof HttpURLConnection) { 
    HttpURLConnection httpConn = (HttpURLConnection) connection; 
    int statusCode = httpConn.getResponseCode(); 
    if (statusCode != 200 /* or statusCode >= 200 && statusCode < 300 */) { 
    is = httpConn.getErrorStream(); 
    } 
} 

Se puede hacer referencia a Javadoc para la explicación . La mejor manera de que manejar esto es el siguiente:

URLConnection connection = url.openConnection(); 
InputStream is = null; 
try { 
    is = connection.getInputStream(); 
} catch (IOException ioe) { 
    if (connection instanceof HttpURLConnection) { 
     HttpURLConnection httpConn = (HttpURLConnection) connection; 
     int statusCode = httpConn.getResponseCode(); 
     if (statusCode != 200) { 
      is = httpConn.getErrorStream(); 
     } 
    } 
} 
+0

"InputStream is = connection.getResponseMessage();" No veo el método getResponseMessage en la clase URLConnection, es parte de HttpUrlConnection, entonces ¿no deberíamos encasillar eso? ¿O podemos reemplazar getResponseMessage por getInputStream, o eso arrojará una excepción? – David

+0

Fue un error tipográfico, es 'connection.getInputStream()'. –

+0

Muy buena y breve respuesta –

8

Es necesario hacer lo siguiente después de llamar openConnection.

  1. Reparto de la URLConnection a HttpURLConnection

  2. getResponseCode llamada

  3. Si la respuesta es un éxito, utilizar getInputStream, de lo contrario usar getErrorStream

(La prueba para el éxito debe ser 200 <= code < 300 porque hay códigos de éxito de HTTP válidos aparte de 200.)


estoy haciendo un rastreador, y la necesidad de obtener los datos de la corriente sin tener en cuenta si se trata de un 200 o no.

Sólo tenga en cuenta que si el código es un 4xx o 5xx, entonces la "información" es probable que sea una página de error de algún tipo.


El punto final que debe hacerse es que siempre se debe respetar el archivo "robots.txt" ... y leer los términos del servicio antes de meterse/raspar el contenido de un sitio cuyos propietarios fuerza cuidado. Simplemente criticar las solicitudes GET es probable que moleste a los propietarios del sitio ... a menos que ya haya llegado a algún tipo de "acuerdo" con ellos.

Cuestiones relacionadas