@Finally等效于播放2.0.x?

时间:2013-01-28 19:03:18

标签: scala playframework playframework-2.0

在我对请求进行日志记录/清理之前,我希望能够向客户端发回响应。

在Play 1.x中,这可以通过@Finally注释实现。我已经阅读了一些帖子,说这些注释被动作组合所取代,但我不清楚如何使用它来模拟@Finally注释。

在我看来,只有在我的自定义操作中的所有逻辑都完成后才会返回响应。

我是否遗漏了某些内容,或者在Play 2.0中无法做到这一点?

[编辑清晰度] 换句话说,我希望能够在收到请求并发送响应后运行逻辑。所以我希望能够构建一个表格的时间表:

  1. 客户端向我的服务器发送请求
  2. 服务器发回200响应,客户端收到该响应
  3. 服务器会执行其他处理,记录等操作
  4. 在游戏中1.x我相信我可以使用@Finally来创建我的附加处理逻辑,让它像我想要的那样工作。

1 个答案:

答案 0 :(得分:2)

动作组合不足以完成这项工作,但是动作组合+未来,或动作组合+演员是实现这一目标的好方法。

行动构成+未来

生成您的响应,在异步上下文中启动日志记录/处理,并同时发送结果。

def LoggedAction(f: Request[AnyContent] => Result) = Action { request =>
  val result = f(request)
  concurrent.future(myLogAction(request, result))
  result
}

行动构成+演员

这是实现这一目标的更简洁方法。与前一种情况一样,生成您的响应,向您的(s)actor发送日志/处理事件,并且并行地发送结果。

import play.api._
import play.api.mvc._
import play.libs._
import akka.actor._

object Application extends Controller with Finally {
  def index = LoggedAction { r =>
      Ok(views.html.index("Your new application is ready."))
  }
}

trait Finally {
  self: Controller =>

  lazy val logActor = Akka.system.actorOf(Props(new LogActor), name = "logActor")

  def LoggedAction(f: Request[AnyContent] => Result) = Action { request =>
    val result = f(request)         // Generate response
    logActor ! LogRequest(request)  // Send log event to LogActor
    println("-> now send page to client")
    result
  }

  case class LogRequest(request: Request[AnyContent]) 

  class LogActor extends Actor {
    def receive = {
      case LogRequest(req) => {
        println(req.host)
        // ....
      }
    }
  }
}

// Console
-> now send page to client
127.0.0.1:9000