scala - 使用 Play 的 EssentialAction 组合

标签 scala playframework playframework-2.0 playframework-2.2

我使用的是 Play 2.2.1,我正在尝试编写自己的 Action 来处理 CORS 请求。我找到了 this但不幸的是它没有编译。

仅供引用,这里是(稍作修改的)代码:

import play.api.mvc._
import scala.concurrent.ExecutionContext

case class CorsAction(action: EssentialAction) extends EssentialAction {
  def apply(request: RequestHeader) = {
    implicit val executionContext: ExecutionContext = play.api.libs.concurrent.Execution.defaultContext
    val origin = request.headers.get("Origin").getOrElse("*")

    if (request.method == "OPTIONS") {
      val cors = Action { request =>
        Ok("").withHeaders(
          "Access-Control-Allow-Origin" -> origin,
          "Access-Control-Allow-Methods" -> "GET, POST, PUT, DELETE, OPTIONS",
          "Access-Control-Allow-Headers" -> "Accept, Origin, Content-type, Authorization, X-Auth-Token, " +
            "X-HTTP-Method-Override, X-Json, X-Prototype-Version, X-Requested-With",
          "Access-Control-Allow-Credentials" -> "true",
          "Access-Control-Max-Age" -> (60 * 60 * 24 * 30).toString)
      }

      cors(request)
    } else {
        action(request).map(res =>
          res.withHeaders(
            "Access-Control-Allow-Origin" -> origin,
            "Access-Control-Allow-Credentials" -> "true"
      ))
    }
  }
}

错误是:

Cors.scala:13: not found: value Ok

我对 Scala 很陌生,对 Play 更是如此!并且无法弄清楚发生了什么。据我所知,我必须使用 EssentialAction 而不仅仅是 Action b/c 我想获取请求的 header 。到目前为止,我发现的所有示例都只涉及 Action。

最佳答案

正如 Will 所说,您缺少 Results 特征。

实现 CorsAction 的一种可能更简洁的方法是使用 ActionBuilders,如 http://www.playframework.com/documentation/2.2.x/ScalaActionsComposition

实现看起来像这样:

import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}

object CorsAction extends ActionBuilder[Request] with Results{
  val MaxAge = 60 * 60 * 24 * 30

  val AllowHeaders = List(
    "Accept", "Origin", "Content-type", "Authorization", "X-Auth-Token",
    "X-HTTP-Method-Override", "X-Json", "X-Prototype-Version", "X-Requested-With")

  val AllowMethods = List("GET", "POST", "PUT", "DELETE", "OPTIONS")

  val AllowCredentials = true

  def cors[A](origin: String) =
    Ok.withHeaders(
      "Access-Control-Allow-Origin" -> origin,
      "Access-Control-Allow-Methods" -> AllowMethods.mkString(", "),
      "Access-Control-Allow-Headers" -> AllowHeaders.mkString(", "),
      "Access-Control-Allow-Credentials" -> AllowCredentials.toString,
      "Access-Control-Max-Age" -> MaxAge.toString)

  def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
    implicit val executionContext = play.api.libs.concurrent.Execution.defaultContext
    val origin = request.headers.get("Origin").getOrElse("*")

    if (request.method == "OPTIONS") {
      Future.successful(cors(origin))
    } else {
      block(request).map(res =>
        res.withHeaders(
          "Access-Control-Allow-Origin" -> origin,
          "Access-Control-Allow-Credentials" -> AllowCredentials.toString
        ))
    }
  }
}

关于scala - 使用 Play 的 EssentialAction 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20530273/

相关文章:

scala - 哪些是模板上默认可用的隐式对象?

java - 涉及M2M关系的Ebean AND查询

Scala HashMap : iterate in insertion order?

scala - 是否有 Python 的 Mechanize 的 Scala 版本?

java - Play Framework 2.1.0 - 使用 Class.forName 注册 JDBC 驱动程序时出现 NoClassDefFoundError

java - 如何设置表之间的关系 Ebean/Play 框架

java - BigtableConfiguration v 运行 Bigtable 模拟器时的 BigtableOptions

scala - 如何在终端中运行 Scala 程序?

java - 如何使用Play框架上传文本文件?

java - 在play framework java中检索POST请求中发送的请求体字符串