迁移到2.2,正确使用Action.async

时间:2014-03-29 21:04:32

标签: playframework playframework-2.0

我正在尝试将Play Framework从2.1升级到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 个答案:

答案 0 :(得分:2)

我刚刚编写了一个可能对my Github有帮助的示例应用。主要想法如下:

Play中的正常操作要么是Action,要么是SimpleResult

def normal = Action { Ok("") }

安全,你实现它的方式,期待一个行动

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

Action.async需要一个SimpleResult的Future,但仍会返回一个Action

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 :(得分:1)

问题是您的Action.async位于另一个Action区域内。您需要Action.async整体阻止Future Result Ok,例如NotFounddef 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") } } } } } 等。

编辑:这是你应该做的:

{{1}}