2014-03-29 93 views
1

我正在嘗試將Play Framework從2.1升級到2.2,並且遇到新的Action.asyc語法遇到困難。例題遷移到2.2,正確使用Action.asyc

我得到:

->Action.async { 
    type mismatch; found : play.api.mvc.Action[play.api.mvc.AnyContent] 
    required: scala.concurrent.Future[play.api.mvc.SimpleResult] 

經過大量谷歌的,我切換到SO社區。示例代碼通道(大量剝離出來無關緊要的細節)這裏:

播放2.1

def homeContent(origin: String, segment: String) = Secured { 
Action { 
    implicit request => 
    val maybeOrigin = Origin.allOrigins.find(p => p.slug == origin) 
    maybeOrigin match { 
     case None => NotFound 
     case Some(originPlace) => { 

      val futureResult = scala.concurrent.Future { 
      DealCard.getTopDealCardsFor(origin, segment) 
      } 
      Async { 
      futureResult.map { 
       case (topDeals) => 
       Ok(「」).as("application/json") 
      } 
      } 
     } 
     } 
    } 
} 

播放2.2.2

def homeContent(origin: String, segment: String) = Secured { 
    Action.async { 
    implicit request => 
    val maybeOrigin = Origin.allOrigins.find(p => p.slug == origin) 
    maybeOrigin match { 
     case None => Future.successful(NotFound) 
     case Some(originPlace) => { 
      Action.async { 
      val futureResult = scala.concurrent.Future { 
       DealCard.getTopDealCardsFor(origin, segment) 
      } 
      futureResult.map { 
       case (topDeals) => 
       Ok("").as("application/json") 
      } 
     } 
     } 
    } 
} 

回答

2

我剛剛寫了一個示例應用程序,可能對my Github有幫助。主要思路如下佈局:在播放

行爲的正常或者預計的行動或SimpleResult

def normal = Action { Ok("") } 

保護,你有它實現的方式,期待一個動作

def secured = Secured { Action { Ok("") } } 

並且Action.async需要一個SimpleResult的未來,但仍然會返回一個動作

def async = Action.async { Future { Ok("") } } 

你似乎在尋找的是一個安全的,需要一個未來[SimpleResult]。要做到這一點,你應該儘量遵循Play documentation for Action Composition佈局的例子爲

trait Security { 

    class AuthenticatedRequest[A](val username: String, request: Request[A]) extends WrappedRequest[A](request) 

    object Secured extends ActionBuilder[AuthenticatedRequest] { 
     def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[SimpleResult]) = { 
     request.session.get("username").map { username => 
      block(new AuthenticatedRequest(username, request)) 
     } getOrElse { 
      Future.successful(Results.Forbidden) 
     } 
     } 
    } 
} 

那麼你應該能夠編寫這樣的事:

def securedAsync = Secured.async { Future { Ok("") } } 
1

的問題是,你的Action.async是在另一個Action塊。你的整體區塊需要Action.async在其中,你會返回一個ResultFuture,例如,OkNotFound

編輯:這是你應該做的:

def homeContent(origin: String, segment: String) = Secured { 
    Action.async { implicit request => 
    val maybeOrigin = Origin.allOrigins.find(p => p.slug == origin) 
    maybeOrigin match { 
     case None => Future.successful(NotFound) 
     case Some(originPlace) => {    
     DealCard.getTopDealCardsFor(origin, segment) map { topDeals => 
      Ok("").as("application/json") 
     } 
     } 
    } 
    } 
} 
+0

的問題是,第二Action.async是返回a:play.api.mvc.Action [play.api.mvc.AnyContent]而不是scala.concurrent.Future [play.api.mvc.SimpleResult]。令人困惑的是Ok()應該是Future [play.api.mvc.SimpleResult]。如果我將它包裝在Future.successful中,它會抱怨Async((scala.concurrent.Future [scala.concurrent.Future [play.api.mvc.SimpleResult]]))的超載。 – andrewl

+0

編輯了這個問題,以澄清我遇到麻煩的地方。感謝你的幫助。 – andrewl

+0

我認爲你誤解了Action.async如何在2.2中工作。它不像舊的'Async'塊,你只是圍繞着'Future',它取代了整個操作。它們不應該嵌套。 – Ryan

相關問題