我正在尝试编写类似于http://www.playframework.com/documentation/2.1.1/ScalaHttpFilters中描述的简单过滤器的过滤器,但我需要访问请求体。下面的文档指出“当我们接下来调用时,我们会返回一个Iteratee。如果你愿意的话,你可以将它包装在Enumeratee中进行一些转换。”我正在试图找出如何包装Iteratee,以便我可以将请求体作为过滤器中的字符串,这样我也可以记录它。
答案 0 :(得分:6)
首先要知道的是,在调用Filter时,尚未解析请求体。这就是为什么它会给你一个RequestHeader
。你必须找出身体的类型,并相应地调用正确的身体解析器。
您可以在CSRF过滤器中找到正文解析的示例(它可以在请求正文的第一个字节中查找CSRF令牌)。
希望它有所帮助。
答案 1 :(得分:0)
我花了一些时间在这上面。 我不是Scala专家,但是效果很好! :)
object AccessLog 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
val bytesToString: Enumeratee[ Array[Byte], String ] = Enumeratee.map[Array[Byte]]{ bytes => new String(bytes) }
val consume: Iteratee[String,String] = Iteratee.consume[String]()
val resultBody : Future[String] = result.body |>>> bytesToString &>> consume
resultBody.map {
body =>
Logger.info(s"${requestHeader.method} ${requestHeader.uri}" +
s" took ${requestTime}ms and returned ${result.header.status}")
val jsonBody = Json.parse(body)
Logger.debug(s"Response\nHeader:\n${result.header.headers.toString}\nBody:\n${Json.prettyPrint(jsonBody)}")
}
result.withHeaders("Request-Time" -> requestTime.toString)
}
}
}
最终结果将身体打印为Json String(漂亮打印)。
答案 2 :(得分:-2)
在路由到操作的控制器方法中,只需调用
即可Map<String, String[]> params = request().queryString();
这将为您提供参数图,然后您可以在其中调用
params.get("someParam")[0]
获取参数(如果它是单个值)。如果param是一个列表,则忽略索引并返回一个数组。