本文介绍了播放2.4:拦截和修改响应正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据播放文档,这是自定义操作看起来应该像这样:

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)
    }
}

但是说,如果我想在每个响应正文后附加"foo",该怎么做?显然,下面的方法不起作用:

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)

有什么想法吗?

更新:值得一提的是,该操作将主要用作控制器中的异步操作:

UPDATE: Something worth mentioning is that this action would be mostly used as asynchronous in the controller:

def test = CustomAction.async {
    //...
}

推荐答案

您需要从Result主体中获取Enumerator[Array[Byte]]并将其提供给iteratee以实际使用结果主体,然后才能对其进行修改. .因此,一个简单的iteratee会消耗结果主体并转换为String:

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")
  }
}

我使用flatMap是因为运行Iteratee.flatten的结果是Future[T].查看 https://www.playframework.com/documentation/2.4.x/Enumerators有关如何使用枚举器/迭代器的更多详细信息.

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.

这篇关于播放2.4:拦截和修改响应正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 02:54