【问题标题】:How to return Enumerator of JSON from ReactiveMongo in Play 2如何在 Play 2 中从 ReactiveMongo 返回 JSON 的枚举器
【发布时间】:2014-03-28 23:42:35
【问题描述】:

在我们的项目中,我们使用ReactiveMongoPlay 2.2.1

问题是,ReactiveMongo返回的Enumerator[A]形式的数据流实际上是一个值对象流,没有逗号分隔,也没有流开始和结束注解,这可以被视为数组打开和关闭语句。

这会给JSON 消费者JS client 带来问题,因为预期的格式是 [A1,A2, ...]

所以我们跳了起来,将我们的 Enumeratee[A] 转换为 Enumerator[String],并检查它是否是第一个元素:

    var first:Boolean = true
    val aToStrs = (as.map(a => {
        if(first) {
            first = false;
            Json.stringify(Json.toJson(a))
        } else {
            "," + Json.stringify(Json.toJson(a))
        }
   }))
   Ok.chunked(
       Enumerator.enumInput(Input.El("[")) andThen
       aToStrs andThen
       Enumerator.enumInput(Input.El("]")) andThen
       Enumerator.enumInput(Input.EOF)
   )

这行得通,但感觉就像在发明轮子。

对于这个常见问题,有更好的解决方案吗?

【问题讨论】:

  • 不敢相信没有更好的解决方案:/

标签: scala playframework-2.0 enumerator iterate reactivemongo


【解决方案1】:

如果您使用 comet 或 EventSource,您将不必手工制作生成输出的方法,而且您实际上还可以在客户端中解析响应项以获取项目。使用数组响应将迫使您编写自己的解析代码或等到所有内容都到达客户端,然后才能在 JavaScript 中使用 build int JSON 解析器。

使用 EventSource 协议进行流式播放非常容易,您应该能够执行以下操作:

implicit val cometEncoder = new Comet.CometMessage[JsValue](_.toString)
Ok.chunked(yourEnumerator &> EventSource()).as(EVENT_STREAM)

然后在客户端html中:

<script type="text/javascript">
  var es = new EventSource(jsRouter.controllers.Application.streamIt().url)

  es.addEventListener("message", function (event) {
    var item = JSON.parse(event.data)
    // ... do something with the json value ...
  })
</script>

在播放示例项目中有一个示例,您可能还想查看$YOUR_PLAY_DIR/samples/scala/eventsource-clock/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-28
    • 2019-01-13
    • 1970-01-01
    • 2019-07-22
    • 2016-02-21
    • 1970-01-01
    • 2013-01-02
    相关资源
    最近更新 更多