[英]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.