Play Framework 2.2.0 - 使用过滤器和全局对象强制语言
-
22-12-2019 - |
题
我一直在尝试根据应用程序的主机名强制将区域设置放入 Request 对象中。这是通过读取配置图来完成的
package controllers
import play.api.mvc._
import play.api.i18n.Lang
import play.api.Play.current
import scala.actors.Future
object Global extends WithFilters(ForceLocalization)
object ForceLocalization extends Filter {
override def apply(next: (RequestHeader) => Future[SimpleResult])
(rh: RequestHeader): Future[SimpleResult] = {
val arr = models.DomainSettings.forDomain(rh.domain).locale.split("_") // -> "en_US"
val language = arr(0) // -> "en"
val country = if ( arr.length == 1 ) "" else arr(1) // -> "US"
f(rh).map( _.withLang(Lang(language, country)) )
}
}
该代码无法编译。它说:
type mismatch:
[error] found : play.api.mvc.PlainResult
[error] required: play.api.mvc.SimpleResult
[error] f(rh).map( _.withLang(Lang(language, country)) )
有什么建议吗?
注意:我可能使用了不好的方法来实现我的目标,所以如果您有更好的建议,我将很高兴收到您的建议。
解决方案
嗯 - 看来您遇到了与 Play 从 PlainResult
到 SimpleResult
.
当我看着 2.2.0 代码库, PlainResult
是:
sealed trait PlainResult extends Result with WithHeaders[PlainResult]
和 SimpleResult
定义为:
case class SimpleResult(...) extends PlainResult
...这意味着所有的 WithHeaders
方法将返回 PlainResult
s - 这是错误的。
我注意到在 GitHub 上的 2.2.x 代码库, ,已更正:
case class SimpleResult(...) extends PlainResult with WithHeaders[SimpleResult]
...如果您愿意使用候选版本,您可以使用 2.2.2-RC1 其中包含修复程序,根据 发行说明.
如果没有,请采用辅助方法来解决问题,方法是执行以下操作 WithHeaders.withLang
无论如何:
object ForceLocalization extends Filter {
override def apply(next: (RequestHeader) => Future[SimpleResult])
(rh: RequestHeader): Future[SimpleResult] = {
...
next(rh).map( withLang(_, Lang(language, country)) )
}
private def withLang(sr:SimpleResult, lang:Lang) = {
sr.withCookies(Cookie(Play.langCookieName, lang.code))
}
}
不隶属于 StackOverflow