2013-11-27 67 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)) 
    } 
}