关于Java:如何获取HttpURLConnection错误响应代码

How to get HttpURLConnection error response code

当我这样看时,我的问题的典型答案是:

1
2
3
4
5
6
7
8
HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() == 200) {
    _is = httpConn.getInputStream();
} else {
     /* error from server */
    _is = httpConn.getErrorStream();
}

来自Java中的读取错误响应正文

这似乎很合理,但是当我查看HttpURLConnection.getResponseCode()的实现时,它做的第一件事就是调用getInputStream()。根据文档,getInputStream()应该在出现错误时引发IOException,因此,如果响应代码不在200范围内,则上述解决方案将始终引发异常!

我在这里错过了什么吗?如果出现错误,如果给我响应代码的函数会在这种情况下抛出,我应该如何获取响应代码?

这是java.net.HttpURLConnection.java中的getResponseCode()对我来说的样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public int getResponseCode() throws IOException {
    // Call getInputStream() first since getHeaderField() doesn't return
    // exceptions
    getInputStream();
    String response = getHeaderField(0);
    if (response == null) {
        return -1;
    }
    response = response.trim();
    int mark = response.indexOf("") + 1;
    if (mark == 0) {
        return -1;
    }
    int last = mark + 3;
    if (last > response.length()) {
        last = response.length();
    }
    responseCode = Integer.parseInt(response.substring(mark, last));
    if (last + 1 <= response.length()) {
        responseMessage = response.substring(last + 1);
    }
    return responseCode;
}


您显示的是Sun的旧实现

public abstract class HttpURLConnection extends URLConnection

enter image description here

新的HttpURLConnection实现

https://github.com/square/okhttp/blob/master/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpURLConnectionImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Override public final InputStream getInputStream() throws IOException {
    if (!doInput) {
      throw new ProtocolException("This protocol does not support input");
    }

    HttpEngine response = getResponse();

    // if the requested file does not exist, throw an exception formerly the
    // Error page from the server was returned if the requested file was
    // text/html this has changed to return FileNotFoundException for all
    // file types
    if (getResponseCode() >= HTTP_BAD_REQUEST) {
      throw new FileNotFoundException(url.toString());
    }

    return response.getResponse().body().byteStream();
}

 /**
 * Returns an input stream from the server in the case of error such as the requested file (txt,
 * htm, html) is not found on the remote server.
 */

 @Override public final InputStream getErrorStream() {
  try {
  HttpEngine response = getResponse();
      if (HttpEngine.hasBody(response.getResponse())
          && response.getResponse().code() >= HTTP_BAD_REQUEST) {
        return response.getResponse().body().byteStream();
      }
      return null;
    } catch (IOException e) {
      return null;
    }
}

HTTP