【问题标题】:Scala Play 2.5 Form bindFromRequest: Cannot find any HTTP Request here?Scala Play 2.5 Form bindFromRequest:在这里找不到任何 HTTP 请求?
【发布时间】:2017-04-26 17:37:12
【问题描述】:

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

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


【解决方案1】:

您正在寻找的是Implicit Parameters。简而言之:

隐式参数可以像常规或显式参数一样传递。如果您没有显式提供隐式参数,那么编译器将尝试为您传递一个。隐式可以来自不同的地方。来自常见问题解答Where does Scala look for implicits?

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

第 1 项下的隐含。优先于第 2 项下的那些。

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

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

现在你有一个implicit request 在范围内,编译器会自动将它传递给bindFormRequerst

正如我在开头提到的,您也可以显式传递request

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

在后一种情况下,无需将 request 声明为 implicit,因为您显然是在显式传递 request。两种变体是相等的。这取决于你喜欢哪一个。

【讨论】:

    【解决方案2】:

    【讨论】:

    • 这是我不久前做的一个 Play 应用教程的代码。我还写了一篇博客文章,其中可能涵盖了您可能会发现的一些困难。希望对你有帮助pedrorijo.com/blog/play-slick
    • 是的,我明白了......但是从语言上讲,在这种情况下,像 request 这样的参数被限定为隐式意味着什么?
    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    相关资源
    最近更新 更多