我在Play Json for ID中有一个Json序列化器
def idFormat[T] = {
Format(new Reads[Id[T]] {
def reads(jv: JsValue): JsResult[Id[T]] =
JsSuccess(Id[T](jv.as[String]))
}, new Writes[Id[T]] {
def writes(id: Id[T]): JsString = JsString(id.underlying.toString)
})
}
implicit def idFormatter[A]: Format[Id[A]] = idFormat[A]
现在,我想支持序列化Option [Id [_]],但我的所有尝试都是徒劳的。我会怎么写
implicit def optionIdFormatter[Option[A]]: ....
答案 0 :(得分:1)
import play.api.libs.json._
case class Id[T](t: T)
implicit def idFormat[T](implicit tFormat: Format[T]): Format[Id[T]] = Format(
new Reads[Id[T]] {
def reads(jsValue: JsValue): JsResult[Id[T]] = jsValue.validate[T].map(t => Id(t))
},
new Writes[Id[T]] {
def writes(id: Id[T]): JsValue = Json.toJson(id.t)
}
)
implicit def optionFormat[T](implicit tFormat: Format[T]): Format[Option[T]] = Format(
new Reads[Option[T]] {
def reads(jsValue: JsValue): JsResult[Option[T]] = jsValue.validate[T].map(t => Some(t))
},
new Writes[Option[T]] {
def writes(o: Option[T]): JsValue = o.map(t => Json.toJson(t)).getOrElse(JsNull)
}
)
val intIdOpt = Some(Id(5))
val intIdOptJson = Json.toJson(intIdOpt)
val intIdOptJsonString = intIdOptJson.toString()
// intIdOptJsonString: String = 5
val usingOptionIntId1 = Map("id" -> Some(Id(5)))
val usingOptionIntId1JsonString = Json.toJson(usingOptionIntId1).toString()
// usingOptionIntId1JsonString: String = {"id":5}
val usingOptionIntId2 = Map("id" -> Option.empty[Id[Int]])
val usingOptionIntId2JsonString = Json.toJson(usingOptionIntId2).toString()
// usingOptionIntId2JsonString: String = {"id":null}