Bagaimana cara mendapatkan tubuh respons menggunakan HttpURLConnection, ketika kode selain 2xx dikembalikan?

97

Saya bermasalah dengan mengambil respons Json jika server mengembalikan kesalahan. Lihat detailnya di bawah.

Bagaimana saya melakukan permintaan tersebut

Saya menggunakan java.net.HttpURLConnection. Saya menyiapkan properti permintaan, lalu saya lakukan:

conn = (HttpURLConnection) url.openConnection();

Setelah itu, ketika request berhasil, saya mendapat respon Json:

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

... dan masalahnya adalah:

Saya tidak dapat mengambil Json yang diterima ketika server mengembalikan beberapa kesalahan seperti 50x atau 40x ,. Baris berikut menampilkan IOException:

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

Server mengirimkan tubuh dengan pasti, saya melihatnya di alat eksternal Burp Suite:

HTTP/1.1 401 Unauthorized

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

Saya bisa mendapatkan pesan tanggapan (yaitu "Kesalahan Server Internal") dan kode (yaitu "500") menggunakan metode berikut:

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

Tetapi saya tidak dapat mengambil isi permintaan ... mungkin ada beberapa metode yang tidak saya perhatikan di perpustakaan?

kiedysktos
sumber

Jawaban:

133

Jika kode respon tidak 200 atau 2xx, gunakan getErrorStream()bukangetInputStream().

Marquis dari Lorne
sumber
2
dalam kasus saya, memiliki kode respons 403, getErrorStream () mengembalikan null
Sip
68

Untuk memperjelas semuanya, inilah kode kerja saya:

if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 399) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
kiedysktos
sumber
3
HttpURLConnection.getErrorStream()( sun.net.www.protocol.httpimplementasi) kembali nullkecuali responseCode >= 400, jadi pemeriksaan Anda untuk 299 mungkin salah.
vladr
5
Jika Anda menggunakan Java 8, Anda bisa mendapatkan respons sebagai String. String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe
1
Rentang yang benar adalah 200 ... 399, karena 3xx adalah status "pengalihan", bukan kesalahan.
luca.vercelli
3

Ini adalah cara mudah untuk mendapatkan respon sukses dari server seperti PHP echo jika tidak pesan kesalahan.

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);
        }
}
Sharhabeel Hamdan
sumber
Solusi bagus! Terimakasih banyak.
Adrian Smith