【问题标题】:Get Response body from play.api.mvc.Action[AnyContent] in Play framework (Scala)从 Play 框架 (Scala) 中的 play.api.mvc.Action[AnyContent] 获取响应正文
【发布时间】:2014-01-29 15:58:51
【问题描述】:

我有以下 Play (Scala) 代码:

object Experiment extends Controller {

 //routes file directs /genki here
 def genki(name: String) = Action(pipeline(name))

 def pipeline(name: String) = {
   req:play.api.mvc.RequestHeader => {
      val template = views.html.genki(name)
      Experiment.Status(200).apply(template).as("text/html")
   }
 }

 def simple = Action {
   SimpleResult(
      header = ResponseHeader(200, Map(CONTENT_TYPE -> "text/plain")),
      body = Enumerator("Hello World!".getBytes())
   )
 }

}

这可以正常编译并按预期工作。

使用 scala REPL 如何显示实际的 html?

我有:

 scala> val action = simple
 action: play.api.mvc.Action[play.api.mvc.AnyContent] = Action(parser=BodyParser(anyContent))    

我的意思是现在 REPL 中的值引用“action”是一个 Action 对象,它对 AnyContent 是类型约束的(这样说正确吗?)。

我现在如何使用此 Action 打印出 Http Response html 内容?

非常感谢

【问题讨论】:

  • 很抱歉,我不清楚这个问题。您希望在 repl 上打印最终的 html 响应吗?

标签: scala playframework


【解决方案1】:

而不是vptheron描述的手动结果提取,可以使用play.api.test.Helpers

import play.api.test.Helpers._
val result: Future[SimpleResult] = …
val bodyAsBytes: Array[Byte] = contentAsBytes(result)

还有contentAsString

【讨论】:

    【解决方案2】:

    answer by Huw 为基础,这里是完整的工作代码:

    import play.api.test._  
    def getStringFromAction(action:Action[AnyContent]):String = {
      val request = new FakeRequest("fakeMethod", "fakeUrl", new FakeHeaders, "fakeBody")
      val result = action.apply(request).run
      import scala.concurrent.duration._
      Helpers.contentAsString(result)(1000 millis)
    }
    

    您需要包含以下库(默认情况下不包含在 Play 中):play-test_2.11.jarselenium-java.jarselenium-api.jarselenium-chrome-driver.jarselenium-firefox-driver.jarselenium-remote-driver.jarselenium-htmlunit-driver.jar、@987654331 @、htmlunit-core-js.jarhtmlunit.jar。这些在 Play 或 Activator 发行版中可用。你也可以在 build.sbt 中添加一个依赖为explained here

    【讨论】:

    • @Jus12 你知道如何让你的答案与 Play 2.5 一起工作吗? FakeRequest 已经消失,取而代之的是 RequestBuilder,上面的代码现在也需要一个 Akka Materializer。升级到2.5后,以上代码不再编译。
    【解决方案3】:

    Action 没有内容,因为它是一个可用于应用 Request 并获得结果的对象。

    val request: Request[A] = ... // create a request instance
    val resultFuture: Future[SimpleResult] = simple(request)
    
    val bodyAsBytes: Array[Byte] = Await.result(Await.result(resultFuture, timeout.duration).body |>>> Iteratee.consume[Array[Byte]](), timeout.duration)
    

    请注意,对于您的示例,一个空请求就足够了,因为您不使用它。

    另外,请注意SimpleResult 中的bodyEnumerator,您需要对其应用Iteratee,这里我只是应用消费者来获取整个列表。使用了 2 个Await.result

    1. 等待Future[SimpleResult] 完成
    2. 等待Enumerator 完成向Iteratee 发送数据。

    【讨论】:

    • 谢谢,如何实例化一个新的 Request[A] 对象,什么是 [A]?我认为这是一个类型类约束,但我没有得到“A”。我对 Scala 的很多不清楚之处在于不知道我们何时处于 OO 模式或 FP 模式!
    • A 是你想要的任何东西,它是提供给类型构造函数以创建具体类型的类型参数。例如,您可以查看play.api.test.FakeRequest,它由 Play 提供!使单元测试更容易。
    • 谢谢,我确实注意到 api 文档中有一个 play.api.test.FakeRequest 但我无法在 repl 或我的代码中导入它,我猜这意味着它没有附带标准播放发行版..
    • @user3231690 您需要包含库 play-test_2.xx.jar(其中 xx 是您的播放版本)。
    猜你喜欢
    • 1970-01-01
    • 2015-05-07
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 2015-01-20
    • 2019-03-13
    相关资源
    最近更新 更多