玩法2.4:拦截修改响应体

Posted

技术标签:

【中文标题】玩法2.4:拦截修改响应体【英文标题】:Play 2.4: intercept and modify response body 【发布时间】:2015-12-07 09:46:28 【问题描述】:

根据play documentation,自定义操作应该是这样的:

object CustomAction extends ActionBuilder[Request] 
    def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] = 
        block(request)
    

但是如果我想在每个响应正文中附加“foo”,我该怎么做?显然下面不起作用:

block.andThen(result => result.map(r => r.body.toString + "foo")).apply(request)

有什么想法吗?

更新:值得一提的是,这个动作在控制器中主要用作异步:

def test = CustomAction.async 
    //...

【问题讨论】:

【参考方案1】:

您需要从 Result 正文中获取 Enumerator[Array[Byte]] 并将其提供给迭代对象以实际使用结果正文,然后才能对其进行修改。因此,使用结果主体并转换为字符串的简单迭代可能如下所示:

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.flattenFuture[T]。查看https://www.playframework.com/documentation/2.4.x/Enumerators 了解有关如何使用枚举器/迭代器的更多详细信息。

【讨论】:

谢谢,这是可行的,但是有一个问题 - 解决方案默认为 Ok 并将覆盖其他响应类型,例如 BadRequest 我的示例很简单,为了使其更完整,您需要从 ResponseHeader 读取结果状态并适当处理您的新结果

以上是关于玩法2.4:拦截修改响应体的主要内容,如果未能解决你的问题,请参考以下文章

switch变种玩法

Github 新玩法 -- Profile ReadMe

这个中秋最潮酷玩法,必须mark!

Dubbo入门核心玩法二

简单Elixir游戏服设计- 游戏玩法介绍

git的简单玩法