使用"隐含请求"在Play中意味着什么?

Kaz*_*ita 2 scala playframework

我的Scala级别是初学者,我看到了一个明确展示声明的动作方法implicit request=>.我的问题是我们应该清楚地宣布什么类型的情况?我也见过没有声明的方法implicit request=>request=>.有谁可以解释这个优势?

arc*_*chz 8

我不会涵盖的意义implicit,因为它已经回答了在计算器本身阶这里.播放文档还解释了request => 此处的使用,但未提供有用的隐式请求的示例.

TL; DR:如有疑问,请使用implicit request某些组件可能需要的内容.

没有请求的行动

如果request不改变结果,你的代码块将返回,它可以省略,你可以写.

def myAction = Action { Ok("Hello World") }
Run Code Online (Sandbox Code Playgroud)

有要求

另一方面,如果您需要使用请求的内容(标题或正文),则必须添加request参数.一个常见的例子是解析请求的主体:

Action(parse.json) { request => // it works without implicit
  request.body.validate[MyClass].fold(/* do something */)
}
Run Code Online (Sandbox Code Playgroud)

有隐式请求

播放文档鼓励我们将请求参数标记为implicit因为即使您不直接使用请求,您使用的一个组件也可能需要它作为隐式.如果您在某个操作中遇到隐藏的隐式错误,则可能归结为您忘记隐式提出请求.

我认为你可能遇到的一个很好的例子就是国际化API.总而言之,它允许根据Accept-Language请求中的标头自动在模板中注入本地化消息.您所要做的就是将I18nSupport特征添加到控制器并注入一个messagesApi: MessagesApi参数(显然可以定义您的国际化消息).然后,在您的旋转模板中,您可以使用本地化的消息.例如 :

模板:

@()(implicit messages: Messages)
@* 
 message will be in english, spanish, klingon... depending on the supported 
 languages and request Accept-Language header
*@
@messages("say-hello") 
Run Code Online (Sandbox Code Playgroud)

控制器:

class MyController @Inject() (val messageApi: MessageApi) extends Controller with I18nSupport {
  def myAction = Action {implicit request => 
    // We do not have to bother about how messages are injected
    // The I18nSupport trait does the work for us
    Ok(html.myTemplate()) 
  }
 }
Run Code Online (Sandbox Code Playgroud)

为了能够做到这一点,I18nSupport特征包含一个def:

implicit def request2Messages(implicit request: RequestHeader): Messages = /* ... */
Run Code Online (Sandbox Code Playgroud)

它允许Messages自动获取实例(编译器将request2Messages(yourRequest)在需要时隐式调用,但您需要在范围内具有隐式请求(或请求标头).

我看到的另一个例子是在使用某些安全框架时自动获取操作范围内的用户实例.

边注

这种隐含链的烦人问题在于,如果您忘记隐式提出请求,编译器可能会抱怨隐藏Messages范围内的隐含,而实际问题是缺少隐式请求.