基本过滤器Play Framework 2中的访问请求正文 [英] Access Request Body in essential filter Play Framework 2
问题描述
我是Scala的新手. 如 https://www.playframework.com/documentation/2.3中的play framework官方文档中所述.x/ScalaHttpFilters :
I am new to Scala. As mentioned in play framework official documentation in https://www.playframework.com/documentation/2.3.x/ScalaHttpFilters :
Play提供了一个称为EssentialFilter的较低级别的过滤器API,该API 使您可以完全访问请求的正文.
Play provides a lower level filter API called EssentialFilter which gives you full access to the body of the request.
但是在requestHeader
对象中没有任何访问请求正文的方法.
but there is not any method to accessing request body in requestHeader
object.
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)
}
}
}
}
推荐答案
创建EssentialFilter
时实现的抽象方法EssentialFilter.apply
返回EssentialAction
,基本上是从RequestHeader
到一个Iteratee[Array[Byte], Result]
,播放将把http正文的传入字节块送入.
The abstract method EssentialFilter.apply
that you implement when you create an EssentialFilter
returns an EssentialAction
which basically is a function that goes from RequestHeader
to an Iteratee[Array[Byte], Result]
into which play will feed the incoming byte chunks of the http body.
如果您不熟悉iteratee API,则上述签名基本上意味着一种可以接受Array[Byte]
类型数据块并迟早会从中产生Result
的东西.
If you aren't familiar with the iteratee API, the signature above basically means, a thing that will accept chunks of data of the type Array[Byte]
and sooner or later produce a Result
out of those.
正常播放Action
是EssentialAction
的子类,它使用BodyParser
解析正文,然后将结果(Request
既是请求标头又是解析的正文)馈送到依次返回Future[Result]
The normal play Action
's is a subclass of EssentialAction
that parses the body using a BodyParser
and then feeding the result of that (Request
which is both request headers and the parsed body) into a function that in turn returns a Future[Result]
因此,如果您只有一个过滤器,则过滤器中的next: EssentialAction
基本上是实际的控制器操作.您可以采用它的Iteratee[Array[Bytes], Result]
并用某些东西包装它,这使得在正文解析器接触到请求的主体之前,可以访问该请求的主体.
So if you only have one filter, then next: EssentialAction
in your filter is basically the actual controller action. That you get to take its Iteratee[Array[Bytes], Result]
and wrap it with something is what makes it possible to access the body of the request, before the body parser has gotten to touch it.
因此,要实现所需的目标,您需要学习一些有关Iteratees
的工作原理以及如何使用Enumeratees
转换或窥视输入到iteratee中的数据的信息.
So to achieve what you want will require you to learn a bit about how Iteratees
works and how to use Enumeratees
to transform or peek into data fed into an iteratee.
Play框架文档已经获得了有关迭代对象的一些很好的信息: https://www.playframework.com/documentation/2.3.x/Iteratees
The play framework docs has got some pretty good information about iteratees: https://www.playframework.com/documentation/2.3.x/Iteratees
James Roper(技术主管)也发表了一篇不错的博客文章,该文章可能会有所帮助: https://jazzy.id.au/2012/11/06/iteratees_for_imperative_programmers.html
There is also a nice blog article by James Roper (play tech lead) that might help: https://jazzy.id.au/2012/11/06/iteratees_for_imperative_programmers.html
过滤器如何发挥作用,使得无法使用过滤器查看已解析的正文.除非您进行枚举以解析主体,但仍然将字节传递给实际操作(这将使您将主体解析两次).
How filters works in play makes it impossible to look at the parsed body with a filter. Unless you make an enumeratee that will parse the body but still pass the bytes on to the actual action (this will have you parsing the body twice).
如果这是您想要的,最好使用ActionBuilder
并创建自己的自定义Action
,使您可以查看已解析的请求.
If this is what you want you may be better off working with the ActionBuilder
and creating your own custom Action
that will allow you to look at the parsed request.
这篇关于基本过滤器Play Framework 2中的访问请求正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!