web-dev-qa-db-ja.com

2xx以外のコードが返されたときに、HttpURLConnectionを使用して応答本文を取得する方法は?

サーバーがエラーを返した場合、Json応答を取得する際に問題があります。以下の詳細を参照してください。

リクエストの実行方法

Java.net.HttpURLConnectionを使用します。リクエストプロパティを設定してから、次の操作を行います。

conn = (HttpURLConnection) url.openConnection();

その後、リクエストが成功すると、レスポンスJsonが返されます。

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

...そして問題は:

サーバーが50xや40xなどのエラーを返したときに受信したJsonを取得できません。次の行はIOExceptionをスローします。

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

サーバーは確実に本文を送信します。外部ツールBurp Suiteに表示されます。

HTTP/1.1 401 Unauthorized

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

次の方法を使用して、応答メッセージ(つまり、「内部サーバーエラー」)とコード(つまり、「500」)を取得できます。

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

しかし、リクエストの本文を取得できません...多分、ライブラリで気づかなかったメソッドがありますか?

79
kiedysktos

応答コードが200または2xxでない場合、getErrorStream()の代わりにgetInputStream().を使用します

117
user207421

物事を明確にするために、ここに私の作業コードがあります:

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