这应该是一个相当简单的一个缓存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