繁体   English   中英

处理Scala play框架中进行外部URL调用的正确方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM