Scala Play 2.5.0 2.5.1 通过访问结果主体进行过滤
Scala Play 2.5.0 2.5.1 Filtering with access to result body
我没有找到在 Play 2 中将正文放入过滤器中的方法。5.x。
我想创建一个 "BadRequestLogFilter",它应该记录请求和结果,如果我的应用程序 returns 状态代码 400-500
在 Play 2.4.x 中,我使用了 Iteratees,它成功了。
我无法将这段代码迁移到 Play 2。5.x。有人可以在这里给我提示吗?也许将主体放入过滤器的孔方法是个坏主意?
这是我的旧过滤器(在 2.4.x 中正常工作)Play 2.4.x
class BadRequestLogFilter @Inject() (implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
val logger = Logger("bad_status").underlyingLogger
override def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = {
val resultFuture = next(request)
resultFuture.foreach(result => {
val status = result.header.status
if (status < 200 || status >= 400) {
val c = Try(request.tags(Router.Tags.RouteController))
val a = Try(request.tags(Router.Tags.RouteActionMethod))
val body = result.body.run(Iteratee.fold(Array.empty[Byte]) { (memo, nextChunk) => memo ++ nextChunk })
val futResponse = body.map(bytes => new String(bytes))
futResponse.map { response =>
val m = Map("method" -> request.method,
"uri" -> request.uri,
"status" -> status,
"response" -> response,
"request" -> request,
"controller" -> c.getOrElse("empty"),
"actionMethod" -> a.getOrElse("empty"))
val msg = m.map { case (k, v) => s"$k=$v" }.mkString(", ")
logger.info(appendEntries(m), msg)
}
}
})
resultFuture
}
}
我想我只需要在此处有效替换此行:
val body = result.body.run(Iteratee.fold(Array.empty[Byte]) { (memo, nextChunk) => memo ++ nextChunk })
第 2 局结果的 body。5.x 的类型为 HttpEntity
所以一旦你得到结果,你就可以得到 body 然后实现它:
val body = result.body.consumeData(mat)
这里 mat
是您拥有的 implicit Materializer
。这将 return 你一个 Future[ByteString]
然后你可以解码它以获得字符串表示(为简单起见,我在这里省略了未来的处理):
val bodyAsString = body.decodeString("UTF-8")
logger.info(bodyAsString)
我没有找到在 Play 2 中将正文放入过滤器中的方法。5.x。 我想创建一个 "BadRequestLogFilter",它应该记录请求和结果,如果我的应用程序 returns 状态代码 400-500
在 Play 2.4.x 中,我使用了 Iteratees,它成功了。 我无法将这段代码迁移到 Play 2。5.x。有人可以在这里给我提示吗?也许将主体放入过滤器的孔方法是个坏主意?
这是我的旧过滤器(在 2.4.x 中正常工作)Play 2.4.x
class BadRequestLogFilter @Inject() (implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
val logger = Logger("bad_status").underlyingLogger
override def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = {
val resultFuture = next(request)
resultFuture.foreach(result => {
val status = result.header.status
if (status < 200 || status >= 400) {
val c = Try(request.tags(Router.Tags.RouteController))
val a = Try(request.tags(Router.Tags.RouteActionMethod))
val body = result.body.run(Iteratee.fold(Array.empty[Byte]) { (memo, nextChunk) => memo ++ nextChunk })
val futResponse = body.map(bytes => new String(bytes))
futResponse.map { response =>
val m = Map("method" -> request.method,
"uri" -> request.uri,
"status" -> status,
"response" -> response,
"request" -> request,
"controller" -> c.getOrElse("empty"),
"actionMethod" -> a.getOrElse("empty"))
val msg = m.map { case (k, v) => s"$k=$v" }.mkString(", ")
logger.info(appendEntries(m), msg)
}
}
})
resultFuture
}
}
我想我只需要在此处有效替换此行:
val body = result.body.run(Iteratee.fold(Array.empty[Byte]) { (memo, nextChunk) => memo ++ nextChunk })
第 2 局结果的 body。5.x 的类型为 HttpEntity
所以一旦你得到结果,你就可以得到 body 然后实现它:
val body = result.body.consumeData(mat)
这里 mat
是您拥有的 implicit Materializer
。这将 return 你一个 Future[ByteString]
然后你可以解码它以获得字符串表示(为简单起见,我在这里省略了未来的处理):
val bodyAsString = body.decodeString("UTF-8")
logger.info(bodyAsString)