Come ottenere il corpo della risposta utilizzando HttpURLConnection, quando viene restituito un codice diverso da 2xx?


95

Ho problemi con il recupero della risposta Json nel caso in cui il server restituisca un errore. Vedere i dettagli di seguito.

Come eseguo la richiesta

Io uso java.net.HttpURLConnection. Ho impostato le proprietà della richiesta, quindi faccio:

conn = (HttpURLConnection) url.openConnection();

Dopodiché, quando la richiesta ha esito positivo, ottengo la risposta Json:

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

... e il problema è:

Non riesco a recuperare Json ricevuto quando il server restituisce un errore come 50x o 40x ,. La riga seguente genera IOException:

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

Il server invia di sicuro il corpo, lo vedo nello strumento esterno Burp Suite:

HTTP/1.1 401 Unauthorized

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

Posso ricevere un messaggio di risposta (ad esempio "Errore interno del server") e il codice (ad esempio "500") utilizzando i seguenti metodi:

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

Ma non riesco a recuperare il corpo della richiesta ... forse c'è qualche metodo che non ho notato nella libreria?

Risposte:


132

Se il codice di risposta non è 200 o 2xx, utilizza getErrorStream()invece digetInputStream().


2
nel mio caso, avendo un codice di risposta 403, getErrorStream () restituisce null
Sip

68

Per rendere le cose più chiare, ecco il mio codice di lavoro:

if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 399) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}

3
HttpURLConnection.getErrorStream()( sun.net.www.protocol.httpimplementazione) restituisce a nullmeno che responseCode >= 400, quindi il tuo controllo per 299 non è probabilmente corretto.
vladr

5
Se stai usando Java 8, puoi ottenere la risposta come String. String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe

1
L'intervallo corretto è 200 ... 399, poiché 3xx è uno stato di "reindirizzamento", non un errore.
luca.vercelli

1

Questo è un modo semplice per ottenere una risposta positiva dal server come PHP echo altrimenti un messaggio di errore.

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);
        }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.