当返回2xx以外的代码时,如何使用HttpURLConnection获取响应体?

kie*_*tos 84 java http httpurlconnection

如果服务器返回错误,我在检索Json响应时遇到问题.详情见下文.

我如何执行请求

我用java.net.HttpURLConnection.我设置了请求属性,然后我做:

conn = (HttpURLConnection) url.openConnection();
Run Code Online (Sandbox Code Playgroud)

在那之后,当请求成功时,我得到了Json的回复:

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

......问题是:

当服务器返回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
Run Code Online (Sandbox Code Playgroud)

服务器确定发送正文,我在外部工具Burp Suite中看到它:

HTTP/1.1 401 Unauthorized

{"type":"AuthApiException","message":"AuthApiException","errors":[{"field":"email","message":"Invalid username and/or password."}]}
Run Code Online (Sandbox Code Playgroud)

我可以使用以下方法获得响应消息(即"内部服务器错误")和代码(即"500"):

conn.getResponseMessage();
conn.getResponseCode();
Run Code Online (Sandbox Code Playgroud)

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

use*_*421 122

如果响应代码不是200或2xx,请使用getErrorStream()而不是getInputStream().

  • 在我的情况下,响应代码为403,getErrorStream()返回null (2认同)
  • @Sip 403 是“禁止的”。响应负载是可能的,但不是强制性的。https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3 (2认同)

kie*_*tos 60

为了使事情变得清晰,这是我的工作代码:

if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 299) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用的是Java 8,则可以将响应作为字符串获取。`String responseBody = br.lines()。collect(Collectors.joining());` (4认同)
  • `HttpURLConnection.getErrorStream()`(`sun.net.www.protocol.http`实现)返回`null`,除非`responseCode> = 400`,所以你对299的检查可能是不正确的. (2认同)

Sha*_*dan 8

这是从服务器获得成功响应的简单方法,如 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);
        }
}
Run Code Online (Sandbox Code Playgroud)