Java HttpURLConnection与Android HttpURLConnection的区别

6

我有一段简单的代码,可以在Windows虚拟机上运行:

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

我现在找不到 content-length 头部信息了,是我漏掉了什么吗?


你能在服务器端检查请求头吗?有什么区别吗? - Jason C
内容长度经常被网络提供商删除。尝试关闭移动数据连接,打开Wi-Fi,看是否有所不同。 - alexei-grigoriev
1个回答

9

Android的HttpURLConnection会自动处理一些神奇的事情,如缓存和gzip处理。

因此,如果您没有设置Accept-Encoding:identity,则HUC会将Accept-Encoding:gzip,deflate设置为默认值。由于nginx是一个智能而好的工具,它可能会以gzip编码的形式传递响应。您没有告诉HUC将响应作为gzipped返回给您,但它会为您解压缩该响应并删除标头,因为这是误导性的。

您可以将此视为一个强大的功能,可节省带宽和电台功耗,无需让Android程序员处理gzipdeflate编码。

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

您可以通过在服务器端运行wiresharktcpdump,或者如果您有已root的Android设备,则也可以在客户端上进行此操作来验证我所说的。


2
好的。只需设置connexion.setRequestProperty("Accept-Encoding","identity"); 就可以了。谢谢。 - geh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接