2013-11-27 144 views
1

我对Scala相当陌生 我试图从Play访问Instagram API!和斯卡拉。玩!使用异步Web请求的框架组合操作

def authenticate = Action { 
request => 
    request.getQueryString("code").map { 
    code => 
     WS.url("https://api.instagram.com/oauth/access_token") 
     .post(
     Map("client_id" -> Seq(KEY.key), "client_secret" -> Seq(KEY.secret), "grant_type" -> Seq("authorization_code"), 
      "redirect_uri" -> Seq("http://dev.my.playapp:9000/auth/instagram"), "code" -> Seq(code)) 
    ) onComplete { 
     case Success(result) => Redirect(controllers.routes.Application.instaline).withSession("token" -> (result.json \ "access_token").as[String]) 
     case Failure(e) => throw e 
     } 
    } 
Redirect(controllers.routes.Application.index) 

}

当应用程序执行,最后重定向发生之前在成功的情况下重定向。 请告诉我,如何避免它。此外,让我知道我的代码中的不良做法。

+0

尝试使用等待同伴对象等待完成:Await.ready($ futurevar,Duration.Inf) –

+1

永远不要使用Await.ready,Await.result或Await.anything在游戏应用。你会遇到僵局和各种其他事情。 –

回答

5

使用Play,您会返回结果 - 您不会发送结果。 onComplete方法附加了一个方法,它执行某些操作,但不返回任何内容(注意它的返回值是Unit,即void)。在附加回调之后,您将在最后一行返回Redirect,这不是您想要执行的操作。相反,您希望从WS调用中获得未来,并返回未来。并且要在Play中返回未来,您需要使用Action.async构建器。例如:

def authenticate = Action.async { request => 

    request.getQueryString("code").map { code => 

    WS.url("https://api.instagram.com/oauth/access_token").post(
     Map(
     "client_id" -> Seq(KEY.key), 
     "client_secret" -> Seq(KEY.secret), 
     "grant_type" -> Seq("authorization_code"), 
     "redirect_uri" -> Seq("http://dev.my.playapp:9000/auth/instagram"), 
     "code" -> Seq(code) 
    ) 
    ).map { result => 

     Redirect(controllers.routes.Application.instaline) 
     .withSession("token" -> (result.json \ "access_token").as[String]) 

    } 
    }.getOrElse { 
    Future.successful(Redirect(controllers.routes.Application.index)) 
    } 
}