Playframework:发现类型不匹配 scala.concurrent.Future[play.api.mvc.Result] 需要:play.api.mvc.Result
Playframework: Type mismatch found scala.concurrent.Future[play.api.mvc.Result] required: play.api.mvc.Result
我在 PlayFramework 的控制器中有以下代码:
def auth = Action.async(parse.json) { request =>
{
val authRequest = request.body.validate[AuthRequest]
authRequest.fold(
errors => Future(BadRequest),
auth => {
credentialsManager.checkEmailPassword(auth.email, auth.password).map {
case Some(credential: Credentials) => {
sessionManager.createSession(credential.authAccountId).map { //Throws an error
case Some(authResponse: AuthResponse) => Ok(Json.toJson(authResponse))
case None => InternalServerError
}
}
case (None) => Unauthorized
}
})
}
}
我在上面带有错误注释的行收到以下错误:
Type Mismatch:
[error] found : scala.concurrent.Future[play.api.mvc.Result]
[error] required: play.api.mvc.Result
[error] sessionManager.createSession(credential.authAccountId).map {
那里的 createSession 调用 returns Future[Option[Object]]
但我不知道如何解决这个问题。
任何帮助将不胜感激。
不确定,但这应该有效:
def auth = Action.async(parse.json) { request =>
{
val authRequest = request.body.validate[AuthRequest]
authRequest.fold(
errors => Future(BadRequest),
auth => {
credentialsManager.checkEmailPassword(auth.email, auth.password).flatMap { //flatMap
case Some(credential: Credentials) => {
sessionManager.createSession(credential.authAccountId).map {
case Some(authResponse: AuthResponse) => Ok(Json.toJson(authResponse))
case None => InternalServerError
}
}
case None => Future(Unauthorized) //Wrap it
}
})
}
}
这是对您的代码的简化,带有一些注释。我希望这足以抓住这个想法:
Future(Option("validCredentials")).flatMap {
case Some(credential) => Future("OK")
case None => Future("Unauthorized")
}
//Future[Option[String]].flatMap(Option[String] => Future[String])
//Future[A].flatMap(A => Future[B]) //where A =:= Option[String] and B =:= String
简答:
在 credentialsManager.checkEmailPassword(auth.email, auth.password).map
行中将 .map
更改为 .flatMap
,将 case (None) => Unauthorized
更改为 case None => Future(Unauthorized)
解释:
credentialsManager.checkEmailPassword(auth.email, auth.password)
returns a Future[Option[Credentials]]
并且在其上的映射将始终 return a Future
并且在其内部 sessionManager.createSession(credential.authAccountId)
也 returns a Future
所以,credentialsManager.checkEmailPassword(auth.email, auth.password)
的最终结果是 Future[Future[something]]
为了避免这种情况,你可以改为 flatten
然后 map
它可以完成通过 flatmap
一步
Future("Unauthorized") 这无效请使用 Future.successful(Ok("OK"))
Future.successful(BadRequest(未授权))
我在 PlayFramework 的控制器中有以下代码:
def auth = Action.async(parse.json) { request =>
{
val authRequest = request.body.validate[AuthRequest]
authRequest.fold(
errors => Future(BadRequest),
auth => {
credentialsManager.checkEmailPassword(auth.email, auth.password).map {
case Some(credential: Credentials) => {
sessionManager.createSession(credential.authAccountId).map { //Throws an error
case Some(authResponse: AuthResponse) => Ok(Json.toJson(authResponse))
case None => InternalServerError
}
}
case (None) => Unauthorized
}
})
}
}
我在上面带有错误注释的行收到以下错误:
Type Mismatch:
[error] found : scala.concurrent.Future[play.api.mvc.Result]
[error] required: play.api.mvc.Result
[error] sessionManager.createSession(credential.authAccountId).map {
那里的 createSession 调用 returns Future[Option[Object]]
但我不知道如何解决这个问题。
任何帮助将不胜感激。
不确定,但这应该有效:
def auth = Action.async(parse.json) { request =>
{
val authRequest = request.body.validate[AuthRequest]
authRequest.fold(
errors => Future(BadRequest),
auth => {
credentialsManager.checkEmailPassword(auth.email, auth.password).flatMap { //flatMap
case Some(credential: Credentials) => {
sessionManager.createSession(credential.authAccountId).map {
case Some(authResponse: AuthResponse) => Ok(Json.toJson(authResponse))
case None => InternalServerError
}
}
case None => Future(Unauthorized) //Wrap it
}
})
}
}
这是对您的代码的简化,带有一些注释。我希望这足以抓住这个想法:
Future(Option("validCredentials")).flatMap {
case Some(credential) => Future("OK")
case None => Future("Unauthorized")
}
//Future[Option[String]].flatMap(Option[String] => Future[String])
//Future[A].flatMap(A => Future[B]) //where A =:= Option[String] and B =:= String
简答:
在 credentialsManager.checkEmailPassword(auth.email, auth.password).map
行中将 .map
更改为 .flatMap
,将 case (None) => Unauthorized
更改为 case None => Future(Unauthorized)
解释:
credentialsManager.checkEmailPassword(auth.email, auth.password)
returns a Future[Option[Credentials]]
并且在其上的映射将始终 return a Future
并且在其内部 sessionManager.createSession(credential.authAccountId)
也 returns a Future
所以,credentialsManager.checkEmailPassword(auth.email, auth.password)
的最终结果是 Future[Future[something]]
为了避免这种情况,你可以改为 flatten
然后 map
它可以完成通过 flatmap
Future("Unauthorized") 这无效请使用 Future.successful(Ok("OK")) Future.successful(BadRequest(未授权))