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


95

サーバーがエラーを返す場合に備えて、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();

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

回答:


132

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


2
私の場合、応答コード403の場合、getErrorStream()はnullを返します
Sip

68

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

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.http実装)はを返さnullないresponseCode >= 400ので、299のチェックはおそらく正しくありません。
vladr 2018年

5
Java 8を使用している場合は、文字列として応答を取得できます。String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe

1
3xxは「リダイレクト」ステータスであり、エラーではないため、正しい範囲は200 ... 399です。
luca.vercelli

1

これは、PHPのようにサーバーから正常な応答を取得する簡単な方法であり、そうでなければエラーメッセージをエコーし​​ます。

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);
        }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.