在Play框架2.2中创建当前请求的结果非常简单。我们只输入:
Ok(views.html.default.render())
然后让它工作就足以用Action包装它,所以最终的代码看起来像:
def index = Action {
Ok(views.html.default.render())
}
没关系。但是现在,我想将响应存储在缓存中以使其更具可伸缩性。我使用EHCache。问题是,当我将它存储到缓存中时,它会抛出
NotSerializableException: play.api.mvc.ActionBuilder$$anon$1
我试图至少缓存自己的结果,但它会抛出
ERROR net.sf.ehcache.store.disk.DiskStorageFactory Disk Write of result-key failed:
java.io.NotSerializableException: play.api.libs.iteratee.Enumerator$$anon$18
我知道,这些值存储在缓存中,但仅存储在内存中,考虑到真正的高负载和许多不同的响应,这可能非常不足。
所以我的问题是,是否有任何方法可以完全缓存Play动作/结果,包括正确的序列化?
我如何尝试使用缓存:我不使用Cached {}
,因为它的行为并不完全符合我的需要,因此我尝试以自己的方式设计它。因此,仅仅为了测试目的,我现在更详细地使用它:
Cache.set("myaction", Action {
Ok(views.html.default.render())
})
或
Cache.set("myresponse", Ok(views.html.default.render()))
但这两种情况都会产生上述异常。
关于缓存:Play缓存API对我来说还不够,所以我通过另外几种方法和新的插件实现扩展了它。起初我尝试只复制默认插件并实现这些扩展但有一些问题,所以我修复了它们是here。这是插件修复。从那以后,它似乎实际上使用了EHCache(从那些例外中猜测)。
答案 0 :(得分:1)
在我看来,你不是试图将结果存储在缓存中,而是操作,然后包含一个无法序列化的闭包,我想这不是你想要做的事情,我猜这是因为你是直接使用EHCache吗?
如果您使用Play缓存API,它应该可以帮助您做正确的事情。您可以在此处找到相关文档:http://www.playframework.com/documentation/2.2.x/ScalaCache
但是响应可能仍然不是可序列化的,如果你真的想要一个序列化为磁盘的缓存,你应该能够缓存模板生成的HTML,因为它基本上是一个字符串,然后重新使用它,但创建一个每个请求的新响应。
(我的直觉是,除了你有一些非常疯狂的复杂模板之外,你每次渲染模板的性能可能会比从磁盘读取它的缓存更好)
答案 1 :(得分:0)