java android 响应码304,我正在尝试使用Java的HttpURLConnection来执行“条件获取”,但我从未获得304状态代码...

Here is my code:

final HttpURLConnection conn = (HttpURLConnection) sourceURL.openConnection();

if (cachedPage != null) {

if (cachedPage.eTag != null) {

conn.setRequestProperty("If-None-Match", cachedPage.eTag);

}

conn.setIfModifiedSince(cachedPage.pageLastModified);

}

conn.connect();

if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {

newCachedPage.eTag = conn.getHeaderField("ETag");

newCachedPage.pageLastModified = conn.getHeaderFieldDate("Last-Modified", 0);

} else if (conn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {

// Never reaches here

}

I never seem to get the HTTP_NOT_MODIFIED response code, even hitting the same server several times in quick succession - where there is definitely no change to the page. Also, conn.getHeaderField("ETag") always seems to respond null, and sometimes conn.getHeaderFieldDate("Last-Modified", 0) returns 0. I've tried this against a variety of web servers.

Can anyone tell me what I'm doing wrong?

解决方案

You're all dependent on the server config.

If you get an Expires response header, then it just means that you don't need to request anything until the specified expire time. If you get a Last-Modified response header, then it means that you should be able to use If-Modified-Since to test it. If you get an ETag response header, then it means that you should be able to use If-None-Match to test it.

Lets take http://cdn3.sstatic.net/stackoverflow/img/favicon.ico as an example (the Stackoverflow's favicon image):

URLConnection connection = new URL("http://cdn3.sstatic.net/stackoverflow/img/favicon.ico").openConnection();

System.out.println(connection.getHeaderFields());

This gives:

{null=[HTTP/1.1 200 OK], ETag=["9d9bd8b1165cb1:0"], Date=[Wed, 17 Aug 2011 17:57:07 GMT], Content-Length=[1150], Last-Modified=[Wed, 06 Oct 2010 02:53:46 GMT], Content-Type=[image/x-icon], Connection=[keep-alive], Accept-Ranges=[bytes], Server=[nginx/0.8.36], X-Cache=[HIT], Cache-Control=[max-age=604800]}

Now, do a If-Modified-Since with the same value as Last-Modified:

URLConnection connection = new URL("http://cdn3.sstatic.net/stackoverflow/img/favicon.ico").openConnection();

connection.setRequestProperty("If-Modified-Since", "Wed, 06 Oct 2010 02:53:46 GMT");

System.out.println(connection.getHeaderFields());

This gives as expected a 304:

{null=[HTTP/1.1 304 Not Modified], ETag=["9d9bd8b1165cb1:0"], Date=[Wed, 17 Aug 2011 17:57:42 GMT], Last-Modified=[Wed, 06 Oct 2010 02:53:46 GMT], Connection=[keep-alive], Server=[nginx/0.8.36], X-Cache=[HIT], Cache-Control=[max-age=604800]}

Now, do a If-None-Match with the same value as ETag:

URLConnection connection = new URL("http://cdn3.sstatic.net/stackoverflow/img/favicon.ico").openConnection();

connection.setRequestProperty("If-None-Match", "9d9bd8b1165cb1:0");

System.out.println(connection.getHeaderFields());

This gives unexpectedly a 200:

{null=[HTTP/1.1 200 OK], ETag=["9d9bd8b1165cb1:0"], Date=[Wed, 17 Aug 2011 18:01:42 GMT], Content-Length=[1150], Last-Modified=[Wed, 06 Oct 2010 02:53:46 GMT], Content-Type=[image/x-icon], Connection=[keep-alive], Accept-Ranges=[bytes], Server=[nginx/0.8.36], X-Cache=[HIT], Cache-Control=[max-age=604800]}

Even more surprising, when the both headers are set with random garbage value as ETag, the server still gives a 304. This is an indication that the If-None-Match is completely ignored by the server behind http://cdn3.sstatic.net. That might be a (proxy) configuration issue or be done fully awarely (not for obvious reasons imho).

这个错误通常是由于网络连接中断或服务器关闭连接导致的。以下是几种可能的解决方案: 1. 重试机制:在捕获异常后,可以尝试重新连接服务器,直到成功或达到最大重试次数。 2. 增加超时时间:可以通过设置连接和读取数据的超时时间来避免因网络延迟而导致的连接中断。 3. 使用HTTPS协议:如果您正在使用HTTP协议,可以尝试使用HTTPS协议来发送请求,因为HTTPS具有更好的稳定性和安全性。 下面是一个使用HttpURLConnection的示例代码,包括重试机制和超时设置: ``` public String sendHttpRequest(String urlStr) { HttpURLConnection conn = null; InputStream is = null; BufferedReader br = null; String result = null; int retryCount = 0; int maxRetry = 3; int timeout = 5000; while (retryCount < maxRetry) { try { URL url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(timeout); conn.setReadTimeout(timeout); int responseCode = conn.getResponseCode(); if (responseCode == 200) { is = conn.getInputStream(); br = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } result = sb.toString(); break; } else { retryCount++; continue; } } catch (SocketTimeoutException e) { retryCount++; continue; } catch (IOException e) { e.printStackTrace(); break; } finally { try { if (br != null) { br.close(); } if (is != null) { is.close(); } if (conn != null) { conn.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } } return result; } ``` 注意:此代码仅供参考,具体实现需要根据您的需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值