Scala 在筛选器中播放框架获取响应状态代码

Scala 在筛选器中播放框架获取响应状态代码,scala,filter,playframework,Scala,Filter,Playframework,我有一个过滤器,在这里我对所有传入的请求进行一些记录,比如请求方法、路径等等。我不想访问响应头,我希望它是我记录传入消息所做工作的继续。这是: def apply(next: (RequestHeader) => Future[SimpleResult])(rh: RequestHeader): Future[SimpleResult] = { val result = next(rh) if (!rh.path.startsWith("/assets"))

我有一个过滤器,在这里我对所有传入的请求进行一些记录,比如请求方法、路径等等。我不想访问响应头,我希望它是我记录传入消息所做工作的继续。这是:

  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事件中执行。这是要走的路还是其他想法?

你必须从未来的
结果中获取响应代码,当你的
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
}

为什么不想访问响应头?没有其他方法可以获取响应代码。我更喜欢
映射结果

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
    }

}
onComplete
相比,
map
似乎唯一会错过的事情就是抛出异常。当然,无论如何,这应该会触发
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
}
故障
案例将没有响应,但将是500-内部服务器错误