玩法2.4:拦截并修改响应体
Play 2.4: intercept and modify response body
根据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 {
//...
}
您需要从 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.flatten
是 Future[T]
。查看 https://www.playframework.com/documentation/2.4.x/Enumerators 以了解有关如何使用 Enumerators/Iteratees.
的更多详细信息
根据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 {
//...
}
您需要从 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.flatten
是 Future[T]
。查看 https://www.playframework.com/documentation/2.4.x/Enumerators 以了解有关如何使用 Enumerators/Iteratees.