Scala Play 2.5 Form bindFromRequest:在这里找不到任何 HTTP 请求?
Scala Play 2.5 Form bindFromRequest: Cannot find any HTTP Request here?
我有一个这样实现的控制器操作:
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
然后编译...但是为什么?
你需要一个 implicit request
范围,像这样:https://github.com/pedrorijo91/play-slick3-steps/blob/master/app/controllers/ApplicationController.scala#L11
您要找的是Implicit Parameters。简而言之:
隐式参数可以像常规或显式参数一样传递。如果您没有显式提供隐式参数,那么编译器将尝试为您传递一个。隐式可以来自不同的地方。来自常见问题 Where does Scala look for implicits?:
- First look in current scope
- Implicits defined in current scope
- Explicit imports
- wildcard imports
- Now look at associated types in
- Companion objects of a type
- Implicit scope of an argument’s type (2.9.1)
- Implicit scope of type arguments (2.8.0)
- Outer objects for nested types
- Other dimensions
第 1 项下的隐含项优先于第 2 项下的隐含项。
通过在您的示例中将 request
标记为 implicit
,您声明了一个 "Implicit defined in current scope"。你需要有一个隐含的请求,因为 bindFormRequest
"asks" 你要通过一个。查看其签名:
bindFromRequest()(implicit request: Request[_]): Form[T]
现在你在范围内有一个 implicit request
,编译器会自动将它传递给 bindFormRequerst
。
正如我在开头提到的,您也可以显式传递 request
:
val filledForm = Account.PasswordChangeForm.bindFromRequest()(request)
在后一种情况下,无需将 request
声明为 implicit
,因为您显然明确地传递了 request
。两种变体是相同的。看你喜欢哪一个。
我有一个这样实现的控制器操作:
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
然后编译...但是为什么?
你需要一个 implicit request
范围,像这样:https://github.com/pedrorijo91/play-slick3-steps/blob/master/app/controllers/ApplicationController.scala#L11
您要找的是Implicit Parameters。简而言之:
隐式参数可以像常规或显式参数一样传递。如果您没有显式提供隐式参数,那么编译器将尝试为您传递一个。隐式可以来自不同的地方。来自常见问题 Where does Scala look for implicits?:
- First look in current scope
- Implicits defined in current scope
- Explicit imports
- wildcard imports
- Now look at associated types in
- Companion objects of a type
- Implicit scope of an argument’s type (2.9.1)
- Implicit scope of type arguments (2.8.0)
- Outer objects for nested types
- Other dimensions
第 1 项下的隐含项优先于第 2 项下的隐含项。
通过在您的示例中将 request
标记为 implicit
,您声明了一个 "Implicit defined in current scope"。你需要有一个隐含的请求,因为 bindFormRequest
"asks" 你要通过一个。查看其签名:
bindFromRequest()(implicit request: Request[_]): Form[T]
现在你在范围内有一个 implicit request
,编译器会自动将它传递给 bindFormRequerst
。
正如我在开头提到的,您也可以显式传递 request
:
val filledForm = Account.PasswordChangeForm.bindFromRequest()(request)
在后一种情况下,无需将 request
声明为 implicit
,因为您显然明确地传递了 request
。两种变体是相同的。看你喜欢哪一个。