這應該是一個相當簡單的一個緩存Facebook的圖像時製作的X *頭的感覺......正如經常出現的情況......在桌面Java應用程序
我用Java編寫的桌面應用程序,它必須保留來自Facebook的圖像緩存。
我似乎無法可靠地確定何時有緩存命中或未命中,正如我期望基於資源修改日期一樣。
我注意到,facebook的回覆中的last-modified
標題幾乎總是(在通過下面的方法檢索到的個人資料圖片的情況下)2009年1月1日午夜...使用Chrome瀏覽器瀏覽網站上的幾個頁面資源監視器打開,我發現許多圖像確實將此日期設置爲最後修改的,並且在情況是這樣的情況下,它們也至少傾向於具有X-Backend
,X-Blockid
& X-Cache-by
(或有時X-N
)字段。在其他情況下,last-modified
設置爲某個較早的日期,並且X-*
不存在,還有其他排列(大部分在界面和廣告圖形上顯示)。
到目前爲止,搜索有關這些x-*
標頭的信息,加上HTTP的有限基礎知識,使我對如何正確實現緩存並不瞭解。很明顯,在普通瀏覽器和Facebook服務器之間,確定緩存中的圖像是否是最新的並不麻煩,但我不清楚正在使用哪種機制來確定它。
目前,我有一種方法,在適當的Facebook資源中打開URLConnection
,在緩存中已經存在相應文件的情況下設置ifmodifiedsince
。如果我得到一個304響應代碼,那麼我會返回 - 在緩存文件上調用setLastModified
以獲得更好的效果(部分原因是,現在,圖像緩存將進入SVN &,它們都會在發生碰巧檢查時得到lastModified設置出)。
public static void downloadPicture(String uid) {
try {
URL url = new URL("http://graph.facebook.com/" + uid + "/picture?type=large");
String fileName = "data/images/" + uid + ".jpg";
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
File cachedPic = new File(fileName);
long lastModified = cachedPic.lastModified();
if (cachedPic.exists()) {
conn.setIfModifiedSince(lastModified);
}
conn.connect();
if (conn.getResponseCode() == 304) {
System.out.println("Using cache for " + uid);
cachedPic.setLastModified(conn.getLastModified());
return;
}
System.out.println("Downloading new for " + uid);
ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream());
FileOutputStream fos = new FileOutputStream(fileName);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
fos.close();
} catch (MalformedURLException e) {
System.err.println("This really shouldn't happen...");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
有應該對我這樣做的過程中方式進行無疑是其他方面的改進(上面的代碼所花的時間每個單項的感知量,這顯然是不應該,我相信我可以解決 - 儘管對最佳實踐的評論仍然受歡迎),但是我需要弄清楚的是,爲什麼當有任何緩存文件出現時,我似乎總是得到304,以及確保發送正確請求的正確方法是什麼。
你是對的,當然,這已經發生在我身上,但不知何故,我仍然沒有得到答案。其實,我一段時間沒有重新探討這個問題,我可能會很快再做一次。 – PeterT 2011-06-15 10:33:16