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

Ho un problema con il recupero della risposta Json nel caso in cui il server restituisce un errore. Vedi i dettagli di seguito.

Come eseguo la richiesta

Io uso java.net.HttpURLConnection . Imposto le proprietà delle richieste, quindi faccio:

 conn = (HttpURLConnection) url.openConnection(); 

Dopodiché, quando la richiesta ha esito positivo, ottengo una 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 qualche 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 il body di sicuro, 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 ottenere il 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?

Se il codice di risposta non è 200 o 2xx, utilizzare getErrorStream() anziché getInputStream().

Per rendere le cose chiare, ecco il mio codice funzionante:

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