【问题标题】:How to get response body using HttpURLConnection, when code other than 2xx is returned?当返回 2xx 以外的代码时,如何使用 HttpURLConnection 获取响应正文?
【发布时间】:2014-09-20 15:00:36
【问题描述】:

如果服务器返回错误,我在检索 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();

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

【问题讨论】:

    标签: java http httpurlconnection


    【解决方案1】:

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

    【讨论】:

    • 在我的情况下,响应代码为 403,getErrorStream() 返回 null
    【解决方案2】:

    错误使用了错误的方法,这里是工作代码:

    BufferedReader br = null;
    if (100 <= conn.getResponseCode() && conn.getResponseCode() <= 399) {
        br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    } else {
        br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
    }
    

    【讨论】:

    • HttpURLConnection.getErrorStream()sun.net.www.protocol.http 实现)除非responseCode &gt;= 400,否则返回null,因此您对299 的检查可能不正确。
    • 如果您使用的是 Java 8,您可以获得字符串形式的响应。 String responseBody = br.lines().collect(Collectors.joining());
    • 正确的范围是 200...399,因为 3xx 是“重定向”状态,而不是错误。
    • @luca.vercelli 我认为应该是 100..399,因为 100..199 用于en.wikipedia.org/wiki/…中定义的“信息”响应
    【解决方案3】:

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

    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);
            }
    }
    

    【讨论】:

    • if(...)应该检查更多成功的代码,实际上都是2xx,而不仅仅是200
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2015-02-28
    相关资源
    最近更新 更多