Wie erhalte ich den Antworttext mit HttpURLConnection, wenn ein anderer Code als 2xx zurückgegeben wird?

95

Ich habe ein Problem beim Abrufen der Json-Antwort, falls der Server einen Fehler zurückgibt. Siehe Details unten.

Wie ich die Anfrage durchführe

Ich benutze java.net.HttpURLConnection. Ich richte die Anforderungseigenschaften ein und mache dann:

conn = (HttpURLConnection) url.openConnection();

Danach, wenn die Anfrage erfolgreich ist, erhalte ich die Antwort Json:

br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
sb = new StringBuilder();
String output;
while ((output = br.readLine()) != null) {
  sb.append(output);
}
return sb.toString();

... und das Problem ist:

Ich kann Json nicht abrufen, wenn der Server einen Fehler wie 50x oder 40x zurückgibt. Die folgende Zeile löst eine IOException aus:

br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
// throws java.io.IOException: Server returned HTTP response code: 401 for URL: www.example.com

Der Server sendet sicher Text, ich sehe es im externen Tool Burp Suite:

HTTP/1.1 401 Unauthorized

{"type":"AuthApiException","message":"AuthApiException","errors":[{"field":"email","message":"Invalid username and/or password."}]}

Ich kann eine Antwortnachricht (dh "Interner Serverfehler") und Code (dh "500") mit den folgenden Methoden erhalten:

conn.getResponseMessage();
conn.getResponseCode();

Aber ich kann den Anfragetext nicht abrufen ... Vielleicht gibt es eine Methode, die ich in der Bibliothek nicht bemerkt habe?

kiedysktos
quelle

Antworten:

132

Wenn der Antwortcode nicht 200 oder 2xx ist, verwenden Sie getErrorStream()stattdessengetInputStream().

Marquis von Lorne
quelle
2
In meinem Fall mit einem Antwortcode 403 gibt getErrorStream () null zurück
Sip
68

Um die Dinge kristallklar zu machen, hier ist mein Arbeitscode:

if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 399) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
kiedysktos
quelle
3
HttpURLConnection.getErrorStream()( sun.net.www.protocol.httpImplementierung) wird zurückgegeben, es nullsei denn responseCode >= 400, Ihre Prüfung auf 299 ist wahrscheinlich falsch.
Vladr
5
Wenn Sie Java 8 verwenden, können Sie die Antwort als Zeichenfolge erhalten. String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe
1
Der korrekte Bereich ist 200 ... 399, da 3xx ein "Umleitungsstatus" und kein Fehler ist.
luca.vercelli
guter Punkt, korrigiert
kiedysktos
1

Dies ist eine einfache Möglichkeit, eine erfolgreiche Antwort vom Server zu erhalten, z. B. PHP-Echo, andernfalls eine Fehlermeldung.

BufferedReader br = null;
if (conn.getResponseCode() == 200) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String strCurrentLine;
        while ((strCurrentLine = br.readLine()) != null) {
               System.out.println(strCurrentLine);
        }
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
    String strCurrentLine;
        while ((strCurrentLine = br.readLine()) != null) {
               System.out.println(strCurrentLine);
        }
}
Sharhabeel Hamdan
quelle