【问题标题】:How to read full response from HttpURLConnection?如何读取 HttpURLConnection 的完整响应?
【发布时间】:2014-01-07 15:51:38
【问题描述】:

我在 andorid 中创建了一些代理服务器来修改 http 标头,它工作正常,但我必须将完整响应转发到“顶层”。
如何从 HttpURLConnection 读取整个响应(所有标头、内容、所有内容)?

HttpURLConnection httpURLConnection;
URL url = new URL(ADDRESS);
httpURLConnection = (HttpURLConnection) url.openConnection();
// add headers, write output stream, flush
if (httpURLConnection.getResponseCode() == HttpsURLConnection.HTTP_OK)
{
    Map<String, List<String>> map = httpURLConnection.getHeaderFields();
    System.out.println("Printing Response Header...\n");

    for (Map.Entry<String, List<String>> entry : map.entrySet())
    {
        System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue());
    }

    return new DataInputStream(httpURLConnection.getInputStream());
}

在 getInputStream 中我只收到了内容,有可能有一些带有整个 reposne 的流?

【问题讨论】:

  • 不,HttpUrlConnection 无法做到这一点。但是你可以通过获取响应码、响应消息和所有的headers来模拟它。

标签: java httpurlconnection


【解决方案1】:

没有办法直接使用HttpURLConnection 转储完整的HTTP 响应,但是您可以使用它的各种方法来重建它。例如,

HttpURLConnection httpURLConnection;
URL url = new URL("http://www.google.com");
httpURLConnection = (HttpURLConnection) url.openConnection();
StringBuilder builder = new StringBuilder();
builder.append(httpURLConnection.getResponseCode())
       .append(" ")
       .append(httpURLConnection.getResponseMessage())
       .append("\n");

Map<String, List<String>> map = httpURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet())
{
    if (entry.getKey() == null) 
        continue;
    builder.append( entry.getKey())
           .append(": ");

    List<String> headerValues = entry.getValue();
    Iterator<String> it = headerValues.iterator();
    if (it.hasNext()) {
        builder.append(it.next());

        while (it.hasNext()) {
            builder.append(", ")
                   .append(it.next());
        }
    }

    builder.append("\n");
}

System.out.println(builder);

打印

200 OK
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Date: Tue, 07 Jan 2014 16:06:45 GMT
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
X-XSS-Protection: 1; mode=block
Expires: -1
Alternate-Protocol: 80:quic
Set-Cookie: NID=67=OIu8_xhcxE-UPCSfIoTINvRyOe4ALVhIqan2NUI6LMdRkSJHTPGvNkYeYE--WqPSEPK4c4ubvmjWGUyFgXsa453KHavX9gUeKdzfInU2Q25yWP3YtMhsIhJpUQbYL4gq; expires=Wed, 09-Jul-2014 16:06:45 GMT; path=/; domain=.google.ca; HttpOnly, PREF=ID=4496ed99b812997d:FF=0:TM=1389110805:LM=1389110805:S=jxodjb3UjGJSZGaF; expires=Thu, 07-Jan-2016 16:06:45 GMT; path=/; domain=.google.ca
Content-Type: text/html; charset=ISO-8859-1
Server: gws
Cache-Control: private, max-age=0

然后您可以获取InputStream 并打印其内容。

【讨论】:

  • 我正在尝试获取 inputStream,但是当我将流打印到文本时,它不是完整的文本。我猜它只下载了一半。
  • 您的代码没有建立连接。 httpURLConnection.connect();不见了。
  • @Error 如果没有建立连接,它是如何得到响应的(代码、标题、正文)?不,这段代码显然确实建立了连接,它只是在内部调用getInputStream() 的getResponseCode() 调用中隐式进行。
  • 我几乎没有读过源代码!我只是看文档不幸的是,文档确实强调了docs.oracle.com/javase/7/docs/api/java/net/…,对于未来的读者来说,这是真的grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…
  • 很好的答案,对我帮助很大。谢谢。
【解决方案2】:

当我寻找类似问题时,起初对我来说并不明显,所以我找到了解决方案。

读取正文响应:

readFullyAsString(connection.getInputStream(), "UTF-8");

这来自:https://stackoverflow.com/a/10505933/1281350

public String readFullyAsString(InputStream inputStream, String encoding) throws IOException {
        return readFully(inputStream).toString(encoding);
    }

    private ByteArrayOutputStream readFully(InputStream inputStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, length);
        }
        return baos;
    }

【讨论】:

  • 这并不能完全回答问题。问题是如何获得包括 HTTP 标头在内的完整响应。这只是回答如何读取 InputStream 是简单的部分。
  • 查看这里的单线解决方案,适用于 Java 8:stackoverflow.com/a/45659529/3585768
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多