我有一个过滤器在哪里我记录了所有传入的请求,例如请求方法,路径等。我不想访问响应头,我想将它作为我记录传入消息的延续。这是:
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事件中执行此操作。这是要走的路还是其他任何想法?
答案 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 - 内部服务器错误。