返回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();

但是我无法检索请求正文...也许我没有在库中注意到某些方法?

Answers:


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

5
如果您使用的是Java 8,则可以将响应作为字符串获取。String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe '19

1
正确的范围是200 ... 399,因为3xx是“重定向”状态,而不是错误。
luca.vercelli

1

这是从服务器获得成功响应的简单方法,例如PHP echo,否则会返回错误消息。

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);
        }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.