在ReactiveMongo Play JSON中格式化ISODate表单字段

时间:2017-11-25 01:22:57

标签: json mongodb scala playframework

将MongoDB与Play Framework和ReactiveMongo Play JSON library一起使用;我正在尝试正确配置表单。我在MongoDB中存储了一些日期,这些日期位于ISODate包装器/ monad中,并作为JSObject处理:

   Json.obj("dateOfBirth" -> Json.obj("$date" -> dateTimeLong))

使用automated mapping in Play的案例类示例是:

   case class FormData(_id: Option[BSONObjectID], name: String, dateOfBirth: Option[JSObject])

这是表格:

  object MyForm {

     val form = Form(
        mapping(
          "_id" -> ignored(Option.empty[BSONObjectID]),
          "name" -> nonEmptyText,
          "dateofBirth" -> ? // not `date` or `optional(date)`
        )
     )

  }

我认为我需要自定义绑定dateOfBirth中的form字段,但这是我遇到困难的地方。我找不到包含隐式对象的地方,将新类型格式化为shown here,而this也没有帮助我(看起来它现在可能已经过时)。

我认为bind方法看起来像这样:

  def bind(date: Date, dateFieldName: String): JsObject = {

    val longDate = new DateTime(date.getTime())
      .withZoneRetainFields(DateTimeZone.UTC)
      .withZone(DateTimeZone.getDefault())
      .getMillis

    Json.obj(s"$$$dateFieldName" -> JsNumber(longDate))

  }

但我可能是错的,但尝试一下会很好,因为我说我似乎无法找到插入custom formatter的正确位置 - 我认为这应该在伴侣中FormData的对象(其中格式适用于嵌套字段)。事实并非如此,所以我再次接近社区。感谢您的任何建议 - 特别是如果有更好的方法来解决这个问题。

1 个答案:

答案 0 :(得分:0)

我知道答案就在那里,但绝对不应该如此隐蔽!这个适合任何感受到我痛苦的人。所以我改变了以下内容:

   case class FormData(_id: Option[BSONObjectID], name: String, dateOfBirth: Option[Date])

表格......

  object MyForm {

     val form = Form(
        mapping(
          "_id" -> ignored(Option.empty[BSONObjectID]),
          "name" -> nonEmptyText,
          "dateOfBirth" -> optional(date)
        )(FormData.apply)(FormData.unapply)
     )

  }

现在是关键部分。在案例类(我的 FormData )的伴随对象中,放置以下内容(这是从Stephane Godbillon's answer here更改的):

  implicit val dateRead: Reads[Date] = (__ \ "$date").read[Long].map { date =>
    new Date(date)
  }

  implicit val dateWrite: Writes[Date] = new Writes[Date] {
    def writes(date: Date): JsValue = Json.obj(
      "$date" -> date.getTime
    )
  }