2xx dışındaki bir kod döndürüldüğünde, HttpURLConnection kullanılarak yanıt gövdesi nasıl alınır?


98

Sunucunun hata vermesi durumunda Json yanıtını alırken sorun yaşıyorum. Aşağıdaki ayrıntılara bakın.

Talebi nasıl yerine getiriyorum

Ben kullanıyorum java.net.HttpURLConnection. İstek özelliklerini kurarım, sonra yaparım:

conn = (HttpURLConnection) url.openConnection();

Bundan sonra istek başarılı olduğunda Json yanıtını alıyorum:

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

... ve sorun şu:

Sunucu 50x veya 40x gibi bir hata verdiğinde alınan Json'ı alamıyorum. Aşağıdaki satır IOException'ı atar:

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

Sunucu kesin olarak vücut gönderiyor, bunu harici araç Burp Suite'te görüyorum:

HTTP/1.1 401 Unauthorized

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

Aşağıdaki yöntemleri kullanarak yanıt mesajı (ör. "Dahili Sunucu Hatası") ve kodu (ör. "500") alabilirim:

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

Ama istek gövdesini alamıyorum ... kütüphanede fark etmediğim bir yöntem olabilir mi?

Yanıtlar:


133

Yanıt kodu 200 veya 2xx değilse, getErrorStream()yerine kullanıngetInputStream().


3
benim durumumda, 403 yanıt koduna sahip olmak, getErrorStream () null döndürür
Sip

72

Her şeyi netleştirmek için, işte çalışma kodum:

if (100 <= 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.httpUygulama) döner nullsürece responseCode >= 400, bu nedenle 299 için çek muhtemelen yanlıştır.
vladr

6
Java 8 kullanıyorsanız, yanıtı String olarak alabilirsiniz. String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe

1
Doğru aralık 200 ... 399'dur, çünkü 3xx bir hata değil "yeniden yönlendirme" durumudur.
luca.vercelli

1
@ luca.vercelli 100..399 olması gerektiğini düşünüyorum çünkü 100..199, en.wikipedia.org/wiki/…
WindRider

4

Bu, sunucudan PHP echo gibi başarılı bir yanıt almanın kolay bir yoludur, aksi takdirde bir hata mesajı.

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);
        }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.