如 https://www.playframework.com/documentation/2.3.x/ScalaHttpFilters中的play框架官方文档中所述:
Play provides a lower level filter API called EssentialFilter which
gives you full access to the body of the request.
但是没有任何方法可以访问requestHeader对象中的请求体.
import play.api.Logger import play.api.mvc._ import play.api.libs.concurrent.Execution.Implicits.defaultContext object LoggingFilter extends EssentialFilter { def apply(nextFilter: EssentialAction) = new EssentialAction { def apply(requestHeader: RequestHeader) = { val startTime = System.currentTimeMillis nextFilter(requestHeader).map { result => val endTime = System.currentTimeMillis val requestTime = endTime - startTime Logger.info(s"${requestHeader.method} ${requestHeader.uri}" + s" took ${requestTime}ms and returned ${result.header.status}") result.withHeaders("Request-Time" -> requestTime.toString) } } } }
解决方法
如果你不熟悉iteratee API,那么上面的签名基本上意味着,它将接受Array [Byte]类型的数据块,并且迟早会产生一个Result.
正常播放Action是EssentialAction的子类,它使用BodyParser解析主体,然后将结果(请求,即请求头和解析后的主体)提供给一个函数,该函数又返回一个Future [Result]
因此,如果您只有一个过滤器,那么接下来:过滤器中的EssentialAction基本上是实际的控制器操作.您可以使用它的Iteratee [Array [Bytes],Result]并用一些东西包装它,这样就可以在身体解析器触摸它之前访问请求的主体.
因此,要实现您想要的功能,您需要了解Iteratees的工作原理以及如何使用Enumeratees转换或查看输入到迭代中的数据.
一些起点
play框架文档有一些关于iteratees的非常好的信息:https://www.playframework.com/documentation/2.3.x/Iteratees
詹姆斯·罗珀(扮演技术主管)也有一篇很好的博客文章可能会有所帮助:
https://jazzy.id.au/2012/11/06/iteratees_for_imperative_programmers.html
重要的提示
过滤器如何在游戏中工作,因此无法使用过滤器查看已解析的主体.除非你创建一个将解析主体的枚举,但仍然将字节传递给实际的动作(这将使你解析主体两次).
如果这是您想要的,那么最好使用ActionBuilder并创建自己的自定义Action,以便查看已解析的请求.