我有一个CRUD控制器在我的应用程序与JsonInception完美的作品,但不能用自定义JSON转换器。
按照给定的情况下类:
case class Validity(id: Option[UUID], objectType: String, since: DateTime, until: DateTime, objectId: UUID, validityTargetId: UUID, validityTargetType: String)
我有一个对象的同伴如下:
object Validity extends CrudObject[Validity] {
implicit val reads = Json.reads[Validity]
implicit val writes = Json.writes[Validity]
}
凡我CrudObject是给定的代码特征:
trait CrudObject[T] {
val reads: Reads[T]
val writes: Writes[T]
}
这是必要的,因为我在一个通用界面污物正在工作。 没有这一点,玩的就是无法找到任何隐含的转换器。
所以,我的通用控制器界面污物,是这样的:
trait CrudController[T] extends Controller {
def service: ServiceModule[T]
def companion: CrudObject[T]
def search...
def insert...
implicit def reads: Reads[T] = companion.reads
implicit def writes: Writes[T] = companion.writes
并为每个控制器,我有如下:
object ValidityController extends CrudController[Validity] {
override def service: GenericServiceModule[Validity] = ServiceModule
override def companion: CrudObject[Validity] = Validity
}
好吧,这个设计想法,就像我说的,完美的作品,我需要设计一个自定义的JSON转换器。 是的,我知道,这是很简单的事,但正在发生的事情,我不知道如何摆脱这一点。
现在我正在努力做到以下几点:
implicit val reads: Reads[Validity] = (
(JsPath \ "id").read[String] and
(JsPath \ "objectType").read[String] and
(JsPath \ "since").read[Long] and
(JsPath \ "until").read[Long] and
(JsPath \ "objectId").read[String] and
(JsPath \ "validityTargetId").read[String] and
(JsPath \ "validityTargetType").read[String]
)(unlift(Validity.apply _))
它给我:
Type mismatch, expected: (NotInferedA) => Option[NotInferedB], actual: (CrudObject[Nothing]) => CrudObject[Nothing]
我相信这是发生的Cuz CrudObject是一个特点,并且不能适用,不应用。
总之,去除CrudObject给了我一个类似的错误:
Type mismatch, expected: (NotInferedA) => Option[NotInferedB], actual: (Option[UUID], String, DateTime, DateTime, UUID, UUID, String) => Validity
但即使我能解决这个问题,我不能没有CrudObject由于我GenericCrud想象的生活。
有什么想法吗?
PS:感谢@mz谁一直给我一些帮助,通过计算器=)
UPDATE
我几乎没有使用这种方法:
implicit object validityFormat extends Format[Validity] {
override def writes(o: Validity): JsValue = {
Json.obj(
"id" -> JsString(o.id.getOrElse(null).toString),
"objectType" -> JsString(o.objectType),
"since" -> JsString(o.since.toString),
"until" -> JsString(o.since.toString),
"objectId" -> JsString(o.objectId.toString),
"validityTargetId" -> JsString(o.validityTargetId.toString),
"validityTargetType" -> JsString(o.validityTargetType))
}
override def reads(json: JsValue): JsResult[Validity] = {
JsSuccess(Validity(
(json \ "id").as[Option[UUID]],
(json \ "objectType").as[String],
(json \ "since").as[DateTime],
(json \ "until").as[DateTime],
(json \ "objectId").as[UUID],
(json \ "validityTargetId").as[UUID],
(json \ "validityTargetType").as[String])
)
}
}
使用这种方式,这是从不同的文档斯卡拉组合程序 ,我没有得到以前的错误,这是很好的,没有类型不匹配=)
现在我工作了就弄清楚如何转换到UUID和日期时间。
UPDATE
我这样做,工作的例子,但我接受了@mz答案,因为有样板比我少,但都工作得很好。 最大的区别是,在我的方法,我需要的日期时间和UUID提供了一些自定义的转换器,而@mz办法你不知道!
implicit object UUIDFormatter extends Format[UUID] {
override def reads(json: JsValue): JsResult[UUID] = {
val uuid = json.validate[String]
JsSuccess(UUID.fromString(uuid.get))
}
override def writes(o: UUID): JsValue = {
JsString(o.toString)
}
}
implicit object DateTimeFormatter extends Format[DateTime] {
override def reads(json: JsValue): JsResult[DateTime] = {
val datetime = json.validate[Long]
JsSuccess(new DateTime(datetime.get))
}
override def writes(o: DateTime): JsValue = {
JsNumber(o.getMillis)
}
}
implicit object validityFormat extends Format[Validity] {
override def writes(o: Validity): JsValue = {
Json.obj(
"id" -> JsString(o.id.getOrElse(null).toString),
"objectType" -> JsString(o.objectType),
"since" -> JsNumber(o.since.getMillis),
"until" -> JsNumber(o.since.getMillis),
"objectId" -> JsString(o.objectId.toString),
"validityTargetId" -> JsString(o.validityTargetId.toString),
"validityTargetType" -> JsString(o.validityTargetType))
}
override def reads(json: JsValue): JsResult[Validity] = {
JsSuccess(Validity(
(json \ "id").as[Option[UUID]],
(json \ "objectType").as[String],
(json \ "since").as[DateTime],
(json \ "until").as[DateTime],
(json \ "objectId").as[UUID],
(json \ "validityTargetId").as[UUID],
(json \ "validityTargetType").as[String])
)
}