【问题标题】:How to get HttpURLConnection error response code如何获取 HttpURLConnection 错误响应代码
【发布时间】:2016-03-24 10:26:23
【问题描述】:

当我看到 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;
}

【问题讨论】:

  • 很好奇。当我查看它时,它所做的第一件事就是查看responseCode 是否已设置,如果已设置,则返回它。它所做的下一步 是调用getInputStream(),在try 块中。我建议你再看看。
  • android 的实现有没有可能和一般的java 不一样?
  • @Pragnani 是的,它确实发生了变化。目前他们正在使用自己的实现。
  • 包全名为 java.net.HttpURLConnection (android-21)
  • @DaedalusAlpha - 我给了你解释

标签: java android http


【解决方案1】:

您所展示的是旧的实现

公共抽象类 HttpURLConnection 扩展了 URLConnection

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

适用于 Android 和 Java 应用程序的 HTTP 和 HTTP/2 客户端。有关更多信息,请参阅网站和 wiki。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 2018-12-29
    • 1970-01-01
    相关资源
    最近更新 更多