如何获取HttpURLConnection错误响应代码

时间:2016-03-24 10:26:24

标签: java android http

当我看到SO时,我的问题的典型答案是:

HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() == 200) {
    _is = httpConn.getInputStream();
} else {
     /* error from server */
    _is = httpConn.getErrorStream();
}

来自Read error response body in Java

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

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

以下是java.net.HttpURLConnection.java中的getResponseCode()对我来说:

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

1 个答案:

答案 0 :(得分:-1)

你所展示的是

的太旧实现
  

公共抽象类HttpURLConnection扩展了URLConnection

enter image description here

新的HttpURLConnection实现

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

@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&amp;适用于Android和Java应用程序的HTTP / 2客户端。有关更多信息,请参阅网站和维基。

http://square.github.io/okhttp/

PS。如果你想读取错误蒸汽流:

/**
 *  from sun.misc.IOUtils class.
 *  It's nearly twice as fast as the common implementation using ByteBuffers:
 *  */
public static byte[] readFully(InputStream is, int length, boolean readAll) throws IOException {
    byte[] output = {};
    if (length == -1) length = Integer.MAX_VALUE;
    int pos = 0;
    while (pos < length) {
        int bytesToRead;
        if (pos >= output.length) { // Only expand when there's no room
            bytesToRead = Math.min(length - pos, output.length + 1024);
            if (output.length < pos + bytesToRead) {
                output = Arrays.copyOf(output, pos + bytesToRead);
            }
        } else {
            bytesToRead = output.length - pos;
        }
        int cc = is.read(output, pos, bytesToRead);
        if (cc < 0) {
            if (readAll && length != Integer.MAX_VALUE) {
                throw new EOFException("Detect premature EOF");
            } else {
                if (output.length != pos) {
                    output = Arrays.copyOf(output, pos);
                }
                break;
            }
        }
        pos += cc;
    }
    return output;
}