如何在Play中解析Lang隐式参数

时间:2014-11-05 16:00:00

标签: scala playframework internationalization implicit

我有一个像这样的控制器

def index = Action.async { implicit request =>
implicit val lang = Lang(Language.mapping.lift(request.queryString("country").head).getOrElse("en"))
  ///...
  futureResult.map{...}
  .recover {
      case error =>
        displayError(error)
    }
}

private def displayError(throwable: Throwable)(implicit lang: Lang) = {
    throwable match {     
      case error: NotFoundException => Status(404)(views.html.errors.notFound("resource.notfound"))
   //...
  }
}

错误模板:

@(message: String)(implicit lang: Lang)
<!DOCTYPE html>
<p>@Html(Messages(message))</p>
...

我注意到了一些事情:

  • 如果val lang = ...未定义为隐式,则编译仍然有效,我可以调用displayError方法
  • 如果没有将lang显式传递给displayError,如下所示:displayError(error)(lang),传递给私有方法的值不是我的代码定义的值,而是我的浏览器使用的最后一个(我猜在一个cookie?)

所以查看代码似乎是一个简单的私有方法调用,但Play是在每个方法调用之前做一些隐式值修改,即使是私有方法,即使没有通过路由器?

由于

1 个答案:

答案 0 :(得分:2)

来自Play 2.3.x文档(有关详细信息,请参阅this page):

  

注意:如果范围中有隐式请求,则它将提供与从Accept-Language标头中提取的首选语言对应的隐式Lang值,并匹配其中一个应用程序支持的语言。您应该在模板中添加一个Lang隐式参数,如下所示:@()(隐式lang:Lang)。

所以这是因为你的范围内有implicit个请求。是的,即使对于private方法,只要您的私有方法接受lang作为implicit参数,因为implicit参数将是可传递的。

如果您不想要此行为,请从请求参数中删除implicit或明确提供您自己的语言,这完全正常。