2015-12-07 66 views
3

根據play documentation這是一個自定義操作應該是什麼樣子:播放2.4:攔截和修改響應主體

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

但是說如果我想追加「富」到每個響應的身體,我該怎麼辦那?顯然以下不起作用:

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

任何想法?

UPDATE:東西值得一提的是,這一行動將在控制器中主要用作異步:

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

回答

2

你需要從Result體採取Enumerator[Array[Byte]]和飼料它的iteratee在可以修改之前實際使用結果主體。所以消耗的結果身體和轉換爲字符串的簡單iteratee可能看起來像:

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瞭解更多關於如何使用枚舉器/迭代器的細節。

+0

謝謝,這是工作,但有一個問題 - 解決方案默認爲「好」,並將覆蓋其他響應類型,如「BadRequest」 – Caballero

+0

我的例子本意很簡單,爲了使它更加完整,您需要從ResponseHeader讀取結果狀態並適當地處理新的結果 – josephpconley