【问题标题】:Returning future list in Play for Scala json在 Play for Scala json 中返回未来列表
【发布时间】:2016-11-27 16:18:02
【问题描述】:

抱歉,如果这是一个简单的问题。我需要在 Action.async 方法中返回 Json 结构,但是我不确定如何创建一个嵌入一个已经是未来的列表的未来。有什么建议么?

case class Clazz (a: Int, b: Int)

def index = Action.async { 
       val json = JsObject(Seq(
            "x" -> JsString("1"),
            "list" -> Json.toJson(getList) // this line does not compile
       ))
       Ok(json)
}


def getList = Future {
    val c1 = Clazz (1,1)
    val c2 = Clazz (2,2)
    val list = List(c1,c2)
    list
}

更新:

添加了以下 Writes 对象:

  implicit val cc: Writes[Clazz] = (
      (JsPath \ "a").write[Int] and
      (JsPath \ "b").write[Int] 
  ) (unlift(Clazz.unapply))

【问题讨论】:

    标签: scala playframework playframework-2.5


    【解决方案1】:

    您必须使用map 函数来获得具有预期内容的新Future:

    def index = Action.async { 
      val eventualList: Future[List[Clazz]] = getList
      eventualList.map { list: List[Clazz] =>
        val json = JsObject(Seq(
          "x" -> JsString("1"),
          "list" -> Json.toJson(list) 
        ))
        Ok(json)
      }
    }
    

    【讨论】:

    • 我在Ok(json) 行中收到以下错误:Cannot write an instance of scala.concurrent.Future[play.api.libs.json.JsObject] to HTTP response. Try to define a Writeable[scala.concurrent.Future[play.api.libs.json.JsObject]] 我添加了 Writes 类(请参阅更新),但问题仍然存在
    • 我的回答有误(我让你返回一个包含未来而不是未来[响应]的响应)。现在已经修复了。
    【解决方案2】:

    我通常更喜欢 for/yield 语法,这样如果您以后需要添加更多 Futures,您可以轻松扩展而无需深度嵌套的地图和平面地图。

    def index = Action.async {
       for {
           list <- getList
       } yield {
           val json = JsObject(Seq(
                "x" -> JsString("1"),
                "list" -> Json.toJson(list)
           ))
           Ok(json)
        }
    }
    

    【讨论】:

    • 你的回答也很有帮助,可惜我只能标记一个正确答案
    猜你喜欢
    • 2017-04-07
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2021-02-25
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    相关资源
    最近更新 更多