¿Cómo obtener cuerpo de respuesta utilizando HttpURLConnection, cuando se devuelve un código que no sea 2xx?

Tengo un problema para recuperar la respuesta Json en caso de que el servidor devuelva un error. Vea los detalles abajo.

Cómo realizo la solicitud

Yo uso java.net.HttpURLConnection . Configuré propiedades de solicitud, luego hago:

 conn = (HttpURLConnection) url.openConnection(); 

Después de eso, cuando la solicitud es exitosa, obtengo la respuesta Json:

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

… y el problema es:

No puedo recuperar Json recibido cuando el servidor devuelve algún error como 50x o 40x. La siguiente línea arroja IOException:

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

El servidor envía el cuerpo seguro, lo veo en la herramienta externa Burp Suite:

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

Puedo obtener un mensaje de respuesta (es decir, “Internal Server Error”) y un código (es decir, “500”) utilizando los siguientes métodos:

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

Pero no puedo recuperar el cuerpo de la solicitud … ¿tal vez hay algún método que no noté en la biblioteca?

Si el código de respuesta no es 200 o 2xx, use getErrorStream() lugar de getInputStream().

Para aclarar las cosas, este es mi código de trabajo:

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