[英]Correct way to handle make an external URL call in Scala play framework
我是Scala和Play 2.0的新手,所以这可能是一个非常简单的问题。 我有以下代码(为简便起见,使用伪编码):
var someExternalUrl = ...
def oauth = Action { request =>
val paramMap = request.queryString.map { case (k, v) => k -> v.mkString }
if (paramMap.contains("error")) {
// Redirect to error page
} else {
val d2 = Duration(1000, "millis")
val futureResponse = ws.url(someExternalUrl).withQueryString(...).toString).get()
var m = futureResponse.map(response => {
val json = response.json
val userId: String = (json \ "user_id").as[String]
Redirect(routes.Application.home()).withSession(
"user_id" -> userId
)
})
Await.result(m, d2)
}
}
这是处理对外部UR1的调用结果的正确方法吗? 我看过一些帖子,它们谈到使用onComplete处理期货而不是使用Await,因为它正在阻塞。
正如@curious所评论的那样,Play为此类情况提供了Action.async
。 有关该文档的更多信息: https : //www.playframework.com/documentation/2.5.x/ScalaAsync#Returning-futures
这样的Await
是(几乎?)从来没有一个很好的解决方案
您正在使用Action,因此,必须对返回Future [T]的任何方法调用使用Await.result。
每当您使用返回Future [T]的方法时,请考虑使用Action.async,因为它允许您返回Future [Result]。 从播放2.2或2.3开始,Action.async可用。
以下是您使用Action.async的代码
def oauth = Action { request =>
val paramMap = request.queryString.map { case (k, v) => k -> v.mkString }
if (paramMap.contains("error")) {
// Redirect to error page
} else {
val d2 = Duration(1000, "millis")
val futureResponse = ws.url(someExternalUrl).withQueryString(...).toString).get()
futureResponse.map(response => {
val json = response.json
val userId: String = (json \ "user_id").as[String]
Redirect(routes.Application.home()).withSession(
"user_id" -> userId
)
})
}
}
Play 2.0版本过旧,您应该至少将其更新为2.4,如果可能的话请更新为2.5。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.