簡體   English   中英

scala play 2.1.1 json功能語法將數據映射到不同的格式

[英]scala play 2.1.1 json functional syntax mapping data to a different format

我正在嘗試使用函數語法編寫自定義json序列化程序,我似乎無法找到解決此特定問題的正確方法。 我有幾個joda DateTime對象,我想以特定的格式編寫用於使用它的UI。 有誰能告訴我哪里出錯了?

這是我正在處理的案例類,沒有什么特別的。

case class Banner(
  id: Int = 0,
  ownerId: Int = 0,
  licenseeId: Option[Int] = None,
  statusColor: Option[String] = None,
  content: Option[String] = None,
  displayStart: DateTime = new DateTime(),
  displayEnd: DateTime = new DateTime(),
  created: DateTime = new DateTime(),
  updated: DateTime = new DateTime()
)

這些是我對序列化程序對象的導入。

import play.api.libs.json._
import play.api.libs.functional.syntax._
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat

首先,joda DateTime會隱式轉換為long,因此宏擴展器可以很好地工作,如果這就是我想要的。

object MySerializers {
  implicit val writesBanner = Json.writes[Banner]
}

我需要的是將displayStart和displayEnd對象轉換為特定的字符串格式而不是long值。 這就是我試圖做的事情。

object MySerializers {
  val userDateFormatter = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm a")

  implicit val writesBanner = (
    (__ \ "id").write[Int] and
    (__ \ "ownerId").write[Int] and
    (__ \ "licenseeId").write[Int] and
    (__ \ "statusColor").writeNullable[String] and
    (__ \ "content").writeNullable[String] and
    (__ \ "displayStart").write[DateTime].inmap[String](dt => userDateFormatter.print(dt)) and
    (__ \ "displayEnd").write[DateTime].inmap[String](dt => userDateFormatter.print(dt)) and
    (__ \ "created").write[DateTime] and
    (__ \ "updated").write[DateTime]
  )(unlift(Banner.unapply))
}

但編譯器對此並不滿意,所以我似乎並不理解使用inmap函數的正確方法。

could not find implicit value for parameter fu: 
play.api.libs.functional.InvariantFunctor[play.api.libs.json.OWrites]
[error]     (__ \ "displayStart").write[DateTime].inmap[String](dt =>     
userDateFormatter.print(dt)) and
[error]                                ^

任何建議都非常感謝。

我設法弄清楚了這一點,我使用了錯誤類型的仿函數映射操作,並且使用了我正在向后工作的類型。 以下是更好的功能語法中的讀/寫實現。

implicit val writesBanner = (
    (__ \ "id").write[Int] and
    (__ \ "ownerId").write[Int] and
    (__ \ "licenseeId").writeNullable[Int] and
    (__ \ "statusColor").writeNullable[String] and
    (__ \ "content").writeNullable[String] and
    (__ \ "displayStart").write[String].contramap[DateTime](dt => userDateFormatter.print(dt)) and
    (__ \ "displayEnd").write[String].contramap[DateTime](dt => userDateFormatter.print(dt)) and
    (__ \ "created").write[DateTime] and
    (__ \ "updated").write[DateTime]
  )(unlift(Banner.unapply))

implicit val readsBanner = (
    (__ \ "id").read[Int] and
    (__ \ "ownerId").read[Int] and
    (__ \ "licenseeId").readNullable[Int] and
    (__ \ "statusColor").readNullable[String] and
    (__ \ "content").readNullable[String] and
    (__ \ "displayStart").read[String].fmap[DateTime](dt => DateTime.parse(dt, userDateFormatter)) and
    (__ \ "displayEnd").read[String].fmap[DateTime](dt => DateTime.parse(dt, userDateFormatter)) and
    (__ \ "created").read[DateTime] and
    (__ \ "updated").read[DateTime]
  )(Banner)

我絕對不是這方面的專家,但我很確定你使用inmap的方式是你如何使用contramap / fmap的組合。

那是:

implicit val formatBanner = (
<truncated>
    (__ \ "displayStart").format[String].inmap(DateTime.parse(_, userDateFormatter), userDateFormatter.print(_)) and
<truncated>
  )(Banner.apply, unlift(Banner.unapply))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM