Java HttpURLConnection VS Android HttpURLConnection

时间:2014-03-23 03:13:50

标签: java android httpurlconnection

我有这个在Windows VM上运行的简单代码:

URL url = new URL("http:xxx.xxx.xxx.xxx/api/cities.json");
HttpURLConnection connexion = (HttpURLConnection) url.openConnection();
connexion.setRequestMethod("GET");

System.out.println("response " + connexion.getResponseCode());
connexion.connect();

InputStream is = connexion.getInputStream();

for (String header : connexion.getHeaderFields().keySet()) {
    System.out.println(header + ":" + connexion.getHeaderField(header));
}

提供这些标题

response 200
null:HTTP/1.1 200 OK
X-Frame-Options:SAMEORIGIN
Access-Control-Allow-Origin:*
Vary:Accept-Encoding
Date:Sun, 23 Mar 2014 03:00:06 GMT
Content-Length:1894
Connection:keep-alive
Content-Type:application/json
Server:nginx

Android上提供相同标题的完全相同的代码

03-22 23:10:35.405: I/System.out(23707): null:HTTP/1.1 200 OK
03-22 23:10:35.405: I/System.out(23707): Access-Control-Allow-Origin:*
03-22 23:10:35.405: I/System.out(23707): Connection:keep-alive
03-22 23:10:35.405: I/System.out(23707): Content-Type:application/json
03-22 23:10:35.405: I/System.out(23707): Date:Sun, 23 Mar 2014 03:10:35 GMT
03-22 23:10:35.405: I/System.out(23707): Server:nginx
03-22 23:10:35.405: I/System.out(23707): Vary:Accept-Encoding
03-22 23:10:35.405: I/System.out(23707): X-Android-Received-Millis:1395544235409
03-22 23:10:35.405: I/System.out(23707): X-Android-Response-Source:NETWORK 200
03-22 23:10:35.405: I/System.out(23707): X-Android-Selected-Transport:http/1.1
03-22 23:10:35.405: I/System.out(23707): X-Android-Sent-Millis:1395544235363
03-22 23:10:35.405: I/System.out(23707): X-Frame-Options:SAMEORIGIN

我再也找不到内容长度标题了。我错过了什么?

1 个答案:

答案 0 :(得分:9)

Android HttpURLConnection正在为您透明地做一些神奇的事情,比如缓存和gzip处理。

因此,如果您未设置Accept-Encoding: identity,则HUC会设置Accept-Encoding: gzip,deflate。由于nginx是一个智能的好东西,它可能会传递您的响应gzip编码。你没有告诉HUC把这个回复给你回复,但它会为你解压缩这个回复并丢弃标题,因为这会产生误导。

您可以将此视为一项功能强大的功能,可在不需要Android程序员处理gzipdeflate编码的情况下节省带宽和无线电功耗。

如果您只是将响应流式传输到JSON解析器,您将获得正确大小的未压缩数据,但事先不知道大小。

您可以通过运行wiresharktcpdump服务器端来验证我的说法,或者如果您拥有root设备,那么也有办法在客户端执行此操作。