Làm thế nào để nhận được nội dung phản hồi bằng HttpURLConnection, khi mã khác 2xx được trả về?


95

Tôi gặp sự cố với việc truy xuất phản hồi Json trong trường hợp máy chủ trả về lỗi. Xem chi tiết bên dưới.

Cách tôi thực hiện yêu cầu

Tôi sử dụng java.net.HttpURLConnection. Tôi thiết lập thuộc tính yêu cầu, sau đó tôi thực hiện:

conn = (HttpURLConnection) url.openConnection();

Sau đó, khi yêu cầu thành công, tôi nhận được phản hồi Json:

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

... và vấn đề là:

Tôi không thể truy xuất Json đã nhận khi máy chủ trả về một số lỗi như 50x hoặc 40x,. Dòng sau ném IOException:

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

Máy chủ chắc chắn sẽ gửi nội dung, tôi thấy nó trong công cụ bên ngoài Burp Suite:

HTTP/1.1 401 Unauthorized

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

Tôi có thể nhận được thông báo phản hồi (tức là "Lỗi máy chủ nội bộ") và mã (tức là "500") bằng các phương pháp sau:

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

Nhưng tôi không thể truy xuất nội dung yêu cầu ... có thể có một số phương pháp tôi không nhận thấy trong thư viện?

Câu trả lời:


132

Nếu mã phản hồi không phải là 200 hoặc 2xx, hãy sử dụng getErrorStream()thay vìgetInputStream().


2
trong trường hợp của tôi, có mã phản hồi 403, getErrorStream () trả về null
Sip

68

Để làm cho mọi thứ trở nên rõ ràng, đây là mã làm việc của tôi:

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.httptriển khai) trả về nulltrừ khi responseCode >= 400, vì vậy séc 299 của bạn có thể không chính xác.
vladr

5
Nếu bạn đang sử dụng Java 8, bạn có thể nhận được phản hồi dưới dạng Chuỗi. String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe

1
Phạm vi chính xác là 200 ... 399, vì 3xx là trạng thái "chuyển hướng", không phải là lỗi.
luca.vercelli

1

Đây là một cách dễ dàng để nhận được phản hồi thành công từ máy chủ như PHP echo nếu không thì sẽ có thông báo lỗi.

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);
        }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.