在剧中!框架 2.1.x 给定请求的内容,我看到执行顺序不一致。这导致我尝试实现的请求门控代码出现一些问题。
考虑以下由过滤器、动作包装器和动作组成的示例代码。
object AFilter extends EssentialFilter {
def apply(nextAction: EssentialAction) : EssentialAction = new EssentialAction {
def apply(request: RequestHeader): Iteratee[Array[Byte], Result] = {
def readBody(nextA: EssentialAction, request: RequestHeader): Iteratee[Array[Byte], Result] = {
def step(body: Array[Byte], nextI: Iteratee[Array[Byte],
Result]) (i: Input[Array[Byte]]): Iteratee[Array[Byte], Result] = i match {
case Input.EOF =>
System.err.println("test 1")
Iteratee.flatten(nextI.feed(Input.EOF))
case Input.Empty =>
Cont[Array[Byte], Result](step(body, nextI) _)
case Input.El(e) =>
val curBody = Array.concat(body, e)
Cont[Array[Byte], Result](step(curBody,
Iteratee.flatten(nextI.feed(Input.El(e)))) _)
}
val nextIteratee: Iteratee[Array[Byte], Result] = nextA(request)
Cont[Array[Byte], Result](i => step(Array(), nextIteratee)(i))
}
readBody(nextAction,request)
}
}
}
def testActionWrapper[A](action: Action[A]): Action[A] = {
Action(action.parser) {
request => Async {
System.err.println("test 2")
Future.successful(action(request))
}
}
}
def testAction =
testActionWrapper {
System.err.println("test 3")
Action(parse.empty) { request =>
System.err.println("test 4")
Async {
System.err.println("test 5")
Future.successful(Ok("Ok"))
}
}
}
使用带有正文和 parse.json 的 POST、PUT 或 GET,println 执行的顺序是
测试 3,测试 1,测试 2,测试 4,测试 5
除了“测试 3”首先发生这是我的预期之外,过滤器迭代在动作包装器执行之前完成。但是通过一个没有正文的简单 GET 我看到了这个
测试 3,测试 2,测试 1,测试 4,测试 5
动作包装器在过滤器迭代完成之前执行。这很可能是因为 Action 跳过了它自己的 body 解析迭代的执行。
现在我的问题是,处理这个问题的最好方法是在没有正文的情况下也跳过迭代?或者,也许更重要的是,这是否意味着在高度并发的 Scala Play 世界中!根本无法保证过滤器必须在操作执行之前完成?