Caching an action in a multi-language website using Play Framework's Cached API

安稳与你 提交于 2019-12-30 03:45:10

问题


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?


回答1:


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.




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!