在我对请求进行日志记录/清理之前,我希望能够向客户端发回响应。
在Play 1.x中,这可以通过@Finally注释实现。我已经阅读了一些帖子,说这些注释被动作组合所取代,但我不清楚如何使用它来模拟@Finally注释。
在我看来,只有在我的自定义操作中的所有逻辑都完成后才会返回响应。
我是否遗漏了某些内容,或者在Play 2.0中无法做到这一点?
[编辑清晰度] 换句话说,我希望能够在收到请求并发送响应后运行逻辑。所以我希望能够构建一个表格的时间表:
在游戏中1.x我相信我可以使用@Finally来创建我的附加处理逻辑,让它像我想要的那样工作。
答案 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