我正在尝试使用功能语法编写自定义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)

09-11 19:50