Pregunta

En Java, este código lanza una excepción cuando el resultado HTTP es un rango de 404:

URL url = new URL("http://stackoverflow.com/asdf404notfound");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // throws!

En mi caso, sé que el contenido es 404, pero de todos modos me gustaría leer el cuerpo de la respuesta.

(En mi caso real, el código de respuesta es 403, pero el cuerpo de la respuesta explica el motivo del rechazo, y me gustaría mostrarlo al usuario).

¿Cómo puedo acceder al cuerpo de respuesta?

¿Fue útil?

Solución

Aquí está el informe de error (cerca, no se solucionará, no es un error).

Su consejo es codificar así:

HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
    _is = httpConn.getInputStream();
} else {
     /* error from server */
    _is = httpConn.getErrorStream();
}

Otros consejos

Es el mismo problema que estaba teniendo: HttpUrlConnection devuelve FileNotFoundException si intenta leer el getInputStream () de la conexión.
En su lugar, debe utilizar getErrorStream () cuando el código de estado sea superior a 400.

Más que esto, tenga cuidado, ya que no solo 200 es el código de estado de éxito, incluso 201, 204, etc. a menudo se usan como estados de éxito.

Aquí hay un ejemplo de cómo fui a administrarlo

... connection code code code ...

// Get the response code 
int statusCode = connection.getResponseCode();

InputStream is = null;

if (statusCode >= 200 && statusCode < 400) {
   // Create an InputStream in order to extract the response object
   is = connection.getInputStream();
}
else {
   is = connection.getErrorStream();
}

... callback/response to your handler....

De esta manera, podrá obtener la respuesta necesaria tanto en casos de éxito como de error.

Espero que esto ayude!

En .Net tiene la propiedad Response de la WebException que da acceso a la transmisión EN una excepción. Así que supongo que esta es una buena manera para Java, ...

private InputStream dispatch(HttpURLConnection http) throws Exception {
    try {
        return http.getInputStream();
    } catch(Exception ex) {
        return http.getErrorStream();
    }
}

O una implementación que utilicé. (Es posible que necesite cambios para la codificación u otras cosas. Funciona en el entorno actual).

private String dispatch(HttpURLConnection http) throws Exception {
    try {
        return readStream(http.getInputStream());
    } catch(Exception ex) {
        readAndThrowError(http);
        return null; // <- never gets here, previous statement throws an error
    }
}

private void readAndThrowError(HttpURLConnection http) throws Exception {
    if (http.getContentLengthLong() > 0 && http.getContentType().contains("application/json")) {
        String json = this.readStream(http.getErrorStream());
        Object oson = this.mapper.readValue(json, Object.class);
        json = this.mapper.writer().withDefaultPrettyPrinter().writeValueAsString(oson);
        throw new IllegalStateException(http.getResponseCode() + " " + http.getResponseMessage() + "\n" + json);
    } else {
        throw new IllegalStateException(http.getResponseCode() + " " + http.getResponseMessage());
    }
}

private String readStream(InputStream stream) throws Exception {
    StringBuilder builder = new StringBuilder();
    try (BufferedReader in = new BufferedReader(new InputStreamReader(stream))) {
        String line;
        while ((line = in.readLine()) != null) {
            builder.append(line); // + "\r\n"(no need, json has no line breaks!)
        }
        in.close();
    }
    System.out.println("JSON: " + builder.toString());
    return builder.toString();
}

Sé que esto no responde la pregunta directamente, pero en lugar de usar la biblioteca de conexión HTTP proporcionada por Sun, es posible que desee echar un vistazo a Commons HttpClient , que (en mi opinión) tiene una API mucho más fácil para trabajar.

Primero verifique el código de respuesta y luego use HttpURLConnection.getErrorStream()

InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top