Scala Play 2.5 表单bindFromRequest:此处找不到任何 HTTP 请求?

问题描述 投票:0回答:2

我有一个控制器操作是这样实现的:

def doChangePassword = deadbolt.Restrict(List(Array(Application.USER_ROLE_KEY)))() 
{ request => // <<<<<<<<<<<< here is the request 
  Future {
    val context = JavaHelpers.createJavaContext(request)
    com.feth.play.module.pa.controllers.AuthenticateBase.noCache(context.response())

    val filledForm = Account.PasswordChangeForm.bindFromRequest
    // compilation error here, it can't see the request ^^^^^^^

    if (filledForm.hasErrors) {
      // User did not select whether to link or not link
      BadRequest(views.html.account.password_change(userService, filledForm))
    } else {
      val Some(user: UserRow) = userService.getUser(context.session)
      val newPassword = filledForm.get.password
      userService.changePassword(user, new MyUsernamePasswordAuthUser(newPassword), true)
      Redirect(routes.Application.profile).flashing(
        Application.FLASH_MESSAGE_KEY -> messagesApi.preferred(request)("playauthenticate.change_password.success")
      )
    }
  }
}

上面的实现会导致编译错误:

[error] /home/bravegag/code/play-authenticate-usage-scala/app/controllers/Account.scala:74: Cannot find any HTTP Request here
[error]         val filledForm =  Account.PasswordChangeForm.bindFromRequest
[error]                                                     ^
[error] one error found

但是,如果我将第 2 行更改为:

{ request => // <<<<<<<<<<<< here is the request 

{ implicit request => // <<<<<<<<<<<< here is the request 

然后编译...但是为什么呢?

scala playframework deadbolt-2
2个回答
8
投票

您正在寻找的是隐式参数。简而言之:

隐式参数可以像常规或显式参数一样传递。如果您没有显式提供隐式参数,那么编译器将尝试为您传递一个隐式参数。隐式可以来自不同的地方。来自 FAQ Scala 在哪里寻找隐式?:

  1. 首先查看当前范围
  • 当前作用域中定义的隐式
  • 显式导入
  • 通配符导入
  1. 现在查看
  2. 中的关联类型
  • 类型的伴生对象
  • 参数类型的隐式作用域 (2.9.1)
  • 类型参数的隐式作用域 (2.8.0)
  • 嵌套类型的外部对象
  • 其他尺寸

第 1 项下的隐式优先于第 2 项下的隐式。

通过在示例中将

request
标记为
implicit
,您将声明“在当前范围内隐式定义”。您需要有一个隐式请求,因为
bindFormRequest
“要求”您通过一个。看它的签名:

bindFromRequest()(implicit request: Request[_]): Form[T]

现在范围内已经有了

implicit request
,编译器会自动将其传递给
bindFromRequest

正如我在开头提到的,你也可以明确地传递

request

val filledForm = Account.PasswordChangeForm.bindFromRequest()(request)

在后一种情况下,无需将

request
声明为
implicit
,因为您显然是显式传递
request
。两种变体是相同的。就看你更喜欢哪一个了。


© www.soinside.com 2019 - 2024. All rights reserved.