Java – HttpUrlConnection每次都返回缓存的响应

我正在尝试收集Roblox货币兑换的统计数据进行分析。 因此,我需要最新的数据而不是缓存的结果。 但是,似乎无论我做什么,结果仍然是缓存的。 似乎最直观的选项setUseCaches()没有效果,并且手动将头设置为Cache-Control: no-cache似乎也不起作用。 我使用Fiddler2检查了Cache头,看到它的值是Cache-Control: max-age=0 ,但它似乎也没有改变程序的行为。 以下是相关的代码:

url:

 private final static String URL = "http://www.roblox.com/my/money.aspx#/#TradeCurrency_tab"; 

GET请求:

  URLConnection socket = new URL( URL ).openConnection( ); socket.setUseCaches( false ); socket.setDefaultUseCaches( false ); HttpURLConnection conn = ( HttpURLConnection )socket; conn.setUseCaches( false ); conn.setDefaultUseCaches( false ); conn.setRequestProperty( "Pragma", "no-cache" ); conn.setRequestProperty( "Expires", "0" ); conn.setRequestProperty( "Cookie", ".ROBLOSECURITY=" + ROBLOSECURITY ); conn.setRequestProperty( "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" ); conn.setRequestProperty( "Accept-Language", "en-US,en;q=0.8" ); conn.setRequestProperty( "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" ); conn.setDoInput( true ); conn.setRequestMethod( "GET" ); conn.connect(); Scanner data = new Scanner( conn.getInputStream() ); data.useDelimiter( "\\A" ); String result = data.next(); data.close( ); conn.disconnect(); 

注意每次重新启动程序时它返回一个唯一的结果,但在程序运行时没有返回,这可能是也可能不重要。

更新:

Wireshark分析(自上次以来我调整了一下我的代码):

 GET /my/money.aspx HTTP/1.1 Pragma: no-cache Expires: 0 Cookie: .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|*sensitive* Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36 Cache-Control: no-cache Host: www.roblox.com Connection: keep-alive HTTP/1.1 200 OK Cache-Control: private, s-maxage=0 Content-Type: text/html; charset=utf-8 Set-Cookie: rbx-ip=; domain=roblox.com; path=/; HttpOnly Set-Cookie: RBXSource=rbx_acquisition_time=1/4/2016 12:45:21 AM&rbx_acquisition_referrer=&rbx_medium=Direct&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; domain=roblox.com; expires=Wed, 03-Feb-2016 06:45:21 GMT; path=/ Access-Control-Allow-Credentials: true Set-Cookie: rbx-ip=; domain=roblox.com; path=/; HttpOnly Set-Cookie: RBXSource=rbx_acquisition_time=1/4/2016 12:45:21 AM&rbx_acquisition_referrer=&rbx_medium=Direct&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=1; domain=roblox.com; expires=Wed, 03-Feb-2016 06:45:21 GMT; path=/ Set-Cookie: RBXEventTrackerV2=CreateDate=1/4/2016 12:45:21 AM&rbxid=59210735&browserid=3940274345; domain=roblox.com; expires=Fri, 22-May-2043 05:45:21 GMT; path=/ Set-Cookie: GuestData=UserID=-856460986; domain=.roblox.com; expires=Fri, 22-May-2043 05:45:21 GMT; path=/ P3P: CP="CAO DSP COR CURa ADMa DEVa OUR IND PHY ONL UNI COM NAV INT DEM PRE" Date: Mon, 04 Jan 2016 06:45:20 GMT Content-Length: 153751 

如果缓存发生在服务器端,请将缓存区附加到URL。

 HttpURLConnection conn = ( HttpURLConnection )new URL( URL + "?_=" + System.currentTimeMillis() ).openConnection( ); 

我注意到你没有告诉本地HttpURLConnection绕过它自己的缓存。

HttpURLConnectionURLConnectioninheritance方法setUseCaches(boolean) 。 从Javadoc for setUseCaches(boolean)

将此URLConnection的useCaches字段的值设置为指定的值。

有些协议会对文档进行缓存。 偶尔,能够“穿过”并忽略缓存(例如,浏览器中的“重新加载”按钮)是很重要的。 如果连接上的UseCaches标志为true,则允许连接使用它可以使用的任何缓存。 如果为false,则忽略缓存。 默认值来自DefaultUseCaches,默认为true。

看到你已经尝试了大多数缓存设置。 它可能不是你的客户,而是他们的服务导致这种情况发生。 我可以从你的wireshark信息中看到你有“Connection Keep-Alive”。 也许您可以尝试将其设置为“连接关闭”,因为您说每次重新启动程序时都会得到非缓存结果。

这在生产环境中可能并不理想,但也许它可以让您对正在发生的事情有所了解。

我缺少上下文(如何多次调用给定的代码片段)来准确地确定问题,但这可能是由于重用socket对象而不是为每个请求实例化一个新对象。

连接打开后, useCache设置无关紧要。 看一下sun.net.www.protocol.http.HttpURLConnection#connect的实现:

 protected void plainConnect() throws IOException { if (connected) { return; } // try to see if request can be served from local cache if (cacheHandler != null && getUseCaches()) { // .. } 

如果连接已打开,它将立即返回并重用现有的InputStream实例。

您是否尝试过以下标题:

 Cache-Control: no-cache Pragma: no-cache If-Modified-Since: Sat, 1 Jan 2000 00:00:00 GMT 

我建议您在打开URLConnection套接字之前对URL执行以下操作:

 URLConnection socket = new URL( URL.replaceFirst("#", "?cacheFrom=" + System.currentTimeMillis()+"#") ).openConnection( );