Play框架在过滤器中获取响应状态代码

时间:2014-06-08 12:18:31

标签: scala filter playframework

我有一个过滤器在哪里我记录了所有传入的请求,例如请求方法,路径等。我不想访问响应头,我想将它作为我记录传入消息的延续。这是:

  def apply(next: (RequestHeader) => Future[SimpleResult])(rh: RequestHeader): Future[SimpleResult] = {
    val result = next(rh)
    if (!rh.path.startsWith("/assets"))
          Logger.info(s"host: ${rh.remoteAddress} ${rh.method} ${rh.path} ${rh.rawQueryString} ${rh.headers.get("user-agent").getOrElse("No user-agent specified")}")
    result
  }

我还要将响应状态代码记录在我记录其余参数的同一行。任何想法我怎么能这样做?或者,我也可以从结果中获取所有这些值,这意味着我必须在onComplete事件中执行此操作。这是要走的路还是其他任何想法?

2 个答案:

答案 0 :(得分:1)

您必须从未来result获取响应代码,当您的apply方法运行时,响应代码尚未确定,因此您实际上没有选择权。代码可以很简单:

def apply(next: (RequestHeader) => Future[SimpleResult])(rh: RequestHeader): Future[SimpleResult] = {
  val result = next(rh)
  if (!rh.path.startsWith("/assets"))
    result.foreach { result =>
      val status = result.header.status
      Logger.info(s"host: ${rh.remoteAddress} ${rh.method} ${rh.path} ${rh.rawQueryString} ${rh.headers.get("user-agent").getOrElse("No user-agent specified")} status: $status")
    }
  result
}

答案 1 :(得分:1)

为什么您不想访问响应标头?获取响应代码不是另一种方式。我更喜欢map结果。

import play.api.libs.concurrent.Execution.Implicits.defaultContext

def apply(next: (RequestHeader) => Future[SimpleResult])(rh: RequestHeader): Future[SimpleResult] = {

    next(rh).map{ response =>
        // This is executed only when the `Future` has been completed successfully.
        if (!rh.path.startsWith("/assets"))
            Logger.info(s"response code: ${response.header.status} host: ${rh.remoteAddress} ${rh.method} ${rh.path} ${rh.rawQueryString} ${rh.headers.get("user-agent").getOrElse("No user-agent specified")}")

        response
    }

}

似乎map唯一会错过vs onComplete的事情就是抛出异常时。当然,无论如何,这应该触发Logger.error。假设您想记录所有内容,那么onComplete必须在这里进行。

import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.util.{Success, Failure}

def apply(next: (RequestHeader) => Future[SimpleResult])(rh: RequestHeader): Future[SimpleResult] = {
    val result: Future[SimpleResult] = next(rh)

    result.onComplete{
        case Success(response) => Logger.info(...)
        case Failure(_) => Logger.info(...)
    }

    result
}

Failure案例没有响应,但会是500 - 内部服务器错误。