Play 2.4: intercept and modify response body

﹥>﹥吖頭↗ 提交于 2019-12-07 12:05:21

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!