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