Frage

In Java, wirft dieser Code eine Ausnahme, wenn das HTTP-Ergebnis 404 Bereich ist:

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

In meinem Fall, ich weiß zufällig, dass der Inhalt 404 ist, aber ich würde immer noch den Körper der Antwort mag sowieso lesen.

(In meinem konkreten Fall der Antwortcode ist 403, aber der Körper der Antwort erklärt den Grund für die Ablehnung, und ich möchte, dass dem Benutzer angezeigt werden soll.)

Wie kann ich den Antworttext zugreifen?

War es hilfreich?

Lösung

Hier ist der Bug-Report (in der Nähe, nicht beheben, kein Fehler).

Ihr Rat ist wie folgt zu codieren:

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

Andere Tipps

Es ist das gleiche Problem, das ich hatte: HttpUrlConnection kehrt FileNotFoundException, wenn Sie versuchen, die getInputStream() von der Verbindung zu lesen.
Sie sollten stattdessen getErrorStream() verwenden, wenn der Statuscode höher als 400 ist.

Mehr als das, bitte seien Sie vorsichtig, da es nicht nur 200 ist für den Erfolg Statuscode zu sein, auch 201, 204, usw. oft als Erfolgsstatus verwendet werden.

Hier ist ein Beispiel dafür, wie ich ging, es zu verwalten

... 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....

Auf diese Weise werden Sie in der Lage sein, die notwendige Antwort auf beide zum Erfolg zu kommen und Fehlerfällen.
Hoffe, das hilft!

In .Net haben Sie die Response-Eigenschaft des WebException, die auf eine Ausnahme Zugriff auf den Stream gibt. Also ich denke, das ist eine gute Möglichkeit für Java ist ...

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

oder eine Implementierung i verwendet. (Möglicherweise müssen Änderungen für die Codierung oder andere Dinge. Arbeitet in der aktuellen Umgebung.)

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

Ich weiß, dass dies nicht die Frage direkt beantwortet, sondern die HTTP-Verbindung Bibliothek von Sun zur Verfügung gestellt von verwenden, können Sie vielleicht einen Blick auf Commons Httpclient , die (meiner Meinung nach) mit einem viel einfacher API hat zu arbeiten.

Überprüfen Sie zunächst den Antwortcode und dann HttpURLConnection.getErrorStream() verwenden

InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top