In order to cache actions per label and language for a given number of seconds, I wrote the following helper method (where label, is the name I give to my action):
def cacheResponseFor(label: String, duration: Int)(action: EssentialAction) = {
Cached({r: RequestHeader => (label + getLanguage(r))}, duration){ action }
}
def getLanguage(request: RequestHeader): String = {
request.cookies
.get(helpers.SessionHelpers.LANGUAGE_SESSION)
.map(_.value)
.getOrElse(helpers.LanguageHelpers.FRENCH)
}
But I'm experiencing something weird, when I try to cache an Action
for 60s and switch languages in the meantime to English from French for example, I keep getting the French version for 60s then it switches to english.
After investigating, I found that method getLanguage
is not called at each call to that action as if the Key gets evaluated only after the caching period ends.
This is not right, I would want this cacheResponseFor
to be called everytime I request my page, the language gets evaluated using getLanguage
and I get the right cached version, i.e. I should end up with 2 cached actions (one per language).
Am I missing something?
Maybe the problem is in the getLanguage
method. Try this, as recommended by the docs:
def getLanguage(request: RequestHeader): String = {
request.acceptLanguages
.map(_.code)
.headOption
.getOrElse(helpers.LanguageHelpers.FRENCH)
}
Also, take a look at Controller.request2lang()
method and see if it could be helpful to you.
I do not know what is the issue you are facing but I did a small proof of concept and there is no issue at all.
package controllers
import play.api.cache.Cached
import play.api.mvc.{Action, Controller, EssentialAction, RequestHeader}
object Caches {
import play.api.Play.current
def cacheResponseFor(label: String, duration: Int)(action: EssentialAction) = {
Cached({r: RequestHeader => label + getLanguage(r)}, duration){ action }
}
def getLanguage(request: RequestHeader): String = {
request.cookies
.get("language")
.map(_.value)
.getOrElse("fr")
}
}
class CachedApplication () extends Controller {
import Caches._
def index = cacheResponseFor("homePage", 60) {
Action { implicit req =>
getLanguage(req) match {
case "fr" =>
Ok("Bonjour le monde")
case _ =>
Ok("Hello world")
}
}
}
}
来源:https://stackoverflow.com/questions/33319654/caching-an-action-in-a-multi-language-website-using-play-frameworks-cached-api