问题
According to play documentation this is what a custom action should look like:
object CustomAction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] = {
block(request)
}
}
But say if I wanted to append "foo" to every response body, how do I do that? Obviously below doesn't work:
block.andThen(result => result.map(r => r.body.toString + "foo")).apply(request)
Any ideas?
UPDATE: Something worth mentioning is that this action would be mostly used as asynchronous in the controller:
def test = CustomAction.async {
//...
}
回答1:
You'll need to take the Enumerator[Array[Byte]]
from the Result
body and feed it to an iteratee to actually consume the result body before you can modify it. So a simple iteratee that consumes the result body and converts to a String might look like:
block.apply(request).flatMap { res =>
Iteratee.flatten(res.body |>> Iteratee.consume[Array[Byte]]()).run.map { byteArray =>
val bodyStr = new String(byteArray.map(_.toChar))
Ok(bodyStr + "foo")
}
}
I used flatMap
as the result of running Iteratee.flatten
is a Future[T]
. Check out https://www.playframework.com/documentation/2.4.x/Enumerators for more details on how to work with Enumerators/Iteratees.
来源:https://stackoverflow.com/questions/34130551/play-2-4-intercept-and-modify-response-body