0

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

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

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

我错过了什么,还是在 Play 2.0 中没有办法做到这一点?

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

  1. 客户端向我的服务器发送请求
  2. 服务器发回 200 响应,客户端收到该响应
  3. 服务器进行额外的处理、记录等

在 play 1.x 中,我相信我可以用 @Finally 注释我的附加处理逻辑,并让它像我想要的那样工作。

4

1 回答 1

2

Action 组合不足以完成这项工作,但 Action 组合 + Future 或 Action 组合 + Actors 是实现这一目标的好方法。

动作组合+未来

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

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

动作组合+演员

这是实现这一目标的一种更清洁的方式。与前一种情况一样,生成您的响应,将日志记录/处理事件发送给您的参与者,并同时发送结果。

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
于 2013-01-29T20:48:45.163 回答