我是JavaFx新手,尝试在我的应用程序中实现它的浏览器。由于在每次新启动时重新加载所有图像相当耗时,我想将它们存储在一些缓存目录中,但一直未能做到这一点。我尝试使用setUserDataDirectory(…)
然后我发现这是一个很好的帖子,但首先,我还不允许在那里发表评论,其次,它似乎只针对JavaFX2.2。那里发布的内容对JavaFx 8仍然适用吗?如果是这样:有没有一种简单的方法来实现这样的URL连接缓存?
非常感谢您的帮助:)
据我所知,这仍然有效。如果您只想实现一个特定的目的,这并不困难,但通用解决方案将更具挑战性。
因此,在深入研究这个问题并学习了URLConnection类两天后,我终于能够提出我自己的(大概是粗糙的)实现,我想在这里与大家分享,以防任何像我这样知之甚少的人在这个线程上绊倒。同样,基本思想是在缓存中只放置特定的文件类型,而不是全部。我选择存储jpg、png、gif和js文件,因为我认为它们是负载最重的文件,尽管其他文件格式也应该可以。第一件事:浏览器。getEngine()。setUserDataDirectory(…) 肯定做不到这项工作。我仍然不知道它有什么好处,但它肯定不会存储图像文件
相反,我所做的基本上是创建5个类:
ResourceCache
、CachedResources
和CachedUrlConnection
类相当小且易于编写。我设计了资源缓存以将url的资源与其对应的CachedResources
对象映射,因此:ConconttHashMap
然后,我实现了CachedUrlConnection类,如下所示:
public class CachedUrlConnection extends URLConnection {
private CachedResource resource;
private ByteArrayInputStream inputStream;
/* Constructors */
public CachedUrlConnection(URL url, CachedResource resource) throws IOException {
super(url);
this.resource = resource;
this.inputStream = new ByteArrayInputStream(resource.getByteData());
}
@Override
public void connect() throws IOException {
// No need to do anything.
}
/* Object Methods */
/* Getters and Setters */
@Override
public String getHeaderField(int index) { ... }
@Override
public String getHeaderField(String key) { ... }
@Override
public Map<String, List<String>> getHeaderFields() { ... }
@Override
public InputStream getInputStream() throws IOException {
return inputStream; // <---- Here, the system can grab the data.
}
}
当查看URLConnection的源代码(例如这里)时,您会很快注意到它的大多数方法实现都是傻瓜,要么返回null,要么抛出未知服务异常。
这很重要:我不知道你需要实现其中的哪一个!
为了找到答案,我使用了MyHttpUrlConnection类,并将其添加到几乎每个函数中
System.out.println("function xyz called!");
super.xyz();
但我很懒,没有检查所有的。到目前为止,一切似乎都很顺利
下一个类是MyHttpUrlConnection。我不能百分之百确定我是否真的需要覆盖HttpURLConnection类,但我还是这样做了,因为它有一个受保护的构造函数,该构造函数将被一个新的sun隐式调用。网www.protocol。http。处理程序
。该处理程序显然不会遵循我们的http策略,所以我只是想确定一下(参见sourcecode line 801)。因此,该类看起来相当空:
public class MyHttpUrlConnection extends HttpURLConnection {
protected MyHttpUrlConnection(URL url, Handler handler) {
this(url, null, handler);
}
public MyHttpUrlConnection(URL url, Proxy proxy) {
this(url, proxy, new MyUrlConnectionHandler()); // <--- No way sneaking around^^
}
protected MyHttpUrlConnection(URL url, Proxy proxy, Handler handler) {
super(url, proxy, handler);
}
public MyHttpUrlConnection(URL url, String host, int port) {
this(url, new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(host, port))); // Taken over from the HttpURLConnection sourcecode.
}
}
现在是最重要的部分:MyUrlConnectionHandler
。再次检查此线程的放置位置。类本身需要的只是覆盖openConnection(URL, Proxy)
函数。在发布我的代码之前,我将向您介绍它的作用。
MyHttpUrlConnection
对象获取服务器上资源的最后修改日期。这应该只调用标头,而不是整个资源。否则,我们不会赢得任何东西。信用归这个线程。不过,我不完全确定我是否在这里正确关闭了URLConnection
。如果有疑问,最好仔细检查;)CachedResources
对象并将其添加到缓存中。CachedUrlConnection
对象。这可能看起来有点愚蠢,因为我们已经拥有了一切,但该函数需要返回一个URLConnection
。MyHttpUrlConnection
对象以正常处理URL。相应的代码如下所示。注意,我使用了Apache的org。阿帕奇。平民io。IOUtils:
@Override
protected URLConnection openConnection(URL url, Proxy proxy) throws IOException {
try {
// Is this some resource that we'd like to cache?
if (ResourceCache.isCachableURL(url)) {
// Retrieve whatever is in the cache first.
ResourceCache cache = ResourceCache.getInstance();
CachedResource resource = cache.getCachedResource(url);
// Open a connection to the server to at least check for the last-modified field.
MyHttpUrlConnection conn = new MyHttpUrlConnection(url, this); // Don't use URL#openConnection to avoid looping!
conn.setRequestMethod("HEAD");
conn.connect();
long lastModified = conn.getLastModified();
// Did we get the last-modified value at all?
if (lastModified == 0) {
throw new Exception("No last-modified value could be read! \n\t" + url);
}
// Resource not cached or out of date?
if (resource == null || resource.getLastModified() < lastModified) {
conn = new MyHttpUrlConnection(url, this);
conn.connect();
InputStream input = conn.getInputStream();
byte[] data = IOUtils.toByteArray(input);
Map<String, List<String>> headerFields = conn.getHeaderFields();
IOUtils.closeQuietly(input);
resource = new CachedResource(url.getFile(), data, headerFields, lastModified); // I use url.getFile() to store the file on my hard drive.
cache.addCachedResource(url, resource);
}
return new CachedUrlConnection(url, resource);
}
} catch (Exception e) {
e.printStackTrace();
}
// Return the default HttpURLConnection in our wrapper class.
return new MyHttpUrlConnection(url, proxy, this);
}
最后一件事:为了安全起见,不要在MyUrlConnectionHandler#openConnection函数中使用URL#openConnection方法。以这种方式写下来,可以很明显地看出原因,但今天,我花了很长时间才弄清楚无限循环来自何处。使用构造函数并调用connect()
。
我希望这对任何人都有帮助,否则这对我来说都是一个很好的锻炼^^
问题内容: 我们希望在生产部署中缓存崩溃,但不要浪费大量时间来弄清楚这样做的系统。我的想法是将具有当前版本号的paras应用于css和js文件的末尾: 两个问题:这会有效地打破缓存吗?由于参数表明这是动态内容,因此该参数会导致浏览器从不缓存该URL的响应吗? 问题答案: 参数表示查询字符串,因此浏览器将认为这是从到的新路径。因此导致它从文件而不是从缓存加载。如你所愿。 而且,浏览器将假定下次调用时
本文向大家介绍vue项目优化之通过keep-alive数据缓存的方法,包括了vue项目优化之通过keep-alive数据缓存的方法的使用技巧和注意事项,需要的朋友参考一下 <keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。 <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<ke
问题内容: 我们希望在生产部署中缓存崩溃,但不要浪费大量时间来弄清楚这样做的系统。我的想法是将具有当前版本号的paras应用于css和js文件的末尾: 两个问题:这会有效地打破缓存吗?由于参数表明这是动态内容,因此该参数会导致浏览器从不缓存该URL的响应吗? 问题答案: 参数表示查询字符串,因此浏览器将认为这是从到的新路径。因此导致它从文件而不是从缓存加载。如你所愿。 而且,浏览器将假定下次调用时
This is the name of the directory where template caches are stored. By default this is "./cache", meaning that it will look for the cache directory in the same directory as the executing php script. Y
假如要开发一个电子商务网站,商品的类别数据Category,是很少发生变化的,而几乎在每个网页,都需要显示商品类别。如果每次都要从mongoDB数据库中查询出商品类别,显然不是一个好主意。 bugu-mongo-cache模块,就是针对这种应用场景的:某个表的数据量很小,很少发生变化,但需要频繁的查询。这样的数据,我们希望能够“常驻内存”,既减少数据库的查询次数,又加快对用户的响应速度。 初始化
数据缓存是指将一些 PHP 变量存储到缓存中,使用时再从缓存中取回。 它也是更高级缓存特性的基础,例如查询缓存 和内容缓存。 如下代码是一个典型的数据缓存使用模式。 其中 $cache 指向缓存组件: // 尝试从缓存中取回 $data $data = $cache->get($key); if ($data === false) { // $data 在缓存中没有找到,则重新计算它