将Future [SomeObject]转换为json

时间:2014-10-30 12:56:39

标签: json scala playframework playframework-json

我正在使用scala并将我的域对象写入json。我像这样使用Play的Json Combinators:

implicit def opensHighlights: Writes[Option[OpensHighlights]] =
  (
    (__ \ 'header).write[String] and
    (__ \ 'topDeviceForOpens).write[String] and
    (__ \ 'percentage).write[String] and
    (__ \ 'percentageOf).write[String])(opensMaybe => {
      val header = Messages("email.summary.highlights.device.opens")
      val percentageOf = Messages("email.summary.highlights.ofAll.opens")
      opensMaybe match {
        case Some(opens) => (
          header,
          deviceTypeName(opens.topDevice),
          Percentage(opens.opensOnThisDevice, opens.totalOpens).stringValue(),
          percentageOf)
        case None => (header, NotApplicable, "0.00", percentageOf)
      }
    })

我在一位更大的作家中使用这位作家:

implicit def summaryHighlightsWrites: Writes[SummaryHighlights] = {
      (
        (__ \ "google").write[Either[GoogleError, GoogleHighlights]] and
        (__ \ "dateWithHighestClickToOpenRate").write[Option[DateHighlights]] and
        (__ \ "subjectLine").write[Option[SubjectLineHighlights]] and
        (__ \ "location").write[Option[LocationHighlights]] and
        (__ \ "link").write[Option[LinkHighlights]] and
        (__ \ "deviceForOpens").write[Option[OpensHighlights]] and
        (__ \ "deviceForClicks").write[Option[ClicksHighlights]])(summary => {
          val result = for {
            google <- summary.google
            dateRange <- summary.dateRange
            subjectLine <- summary.subjectLine
            location <- summary.location
            link <- summary.link
            opensDevice <- summary.opensDevice
            clicksDevice <- summary.clicksDevice
          } yield (google, dateRange, subjectLine, location, link, opensDevice, clicksDevice)

          Await.result(result, 10 seconds)
        })
    }

这是SummaryHighlights类:

case class SummaryHighlights(
  google: Future[Either[GoogleError, GoogleHighlights]],
  dateRange: Future[Option[DateHighlights]],
  subjectLine: Future[Option[SubjectLineHighlights]],
  location: Future[Option[LocationHighlights]],
  link: Future[Option[LinkHighlights]],
  opensDevice: Future[Option[OpensHighlights]],
  clicksDevice: Future[Option[ClicksHighlights]])

我需要这些字段为Future因为它们具有独立的来源并且可以独立地失败/成功。

我想删除那个明确的等待。我想将未来从summaryHighlightsWrites转移到调用此作者的其他代码段。像Play控制器一样。

有任何帮助吗?感谢

1 个答案:

答案 0 :(得分:3)

假设您有一个方法highlights,它返回Future[Option[OpensHighlights]]并且您在范围内定义了隐式Writes[Option[OpensHighlights]],您可以这样做:

def highlights: Future[Option[OpensHighlights]] = ...

def asyncJson = Action.async { request =>
    highlights.map { result =>
        Ok(Json.toJson(result))
    }
}

Future[...]必须映射到Future[Result]内返回的Action.asyncFuture[Result]将专门处理Result而不是普通{{1}}。