使用 Writes trait with unapply 仅序列化特定属性
Serialize only specific attributes using Writes trait with unapply
假设我有这样一个案例 class:
case class Product(ean: Long, name: String, description: String)
我想将这个 class 的对象序列化为 Json,我可以像这样实现 Writes 特性:
implicit val productWrites: Writes[Product] = (
(JsPath \ "ean").write[Long] and
(JsPath \ "name").write[String] and
(JsPath \ "description").write[String]
)(unlift(Product.unapply))
如果我想序列化对象的所有属性,这很好用。现在假设我不想序列化 ean
。我试过这样的事情:
implicit val productWrites: Writes[Product] = (
(JsPath \ "name").write[String] and
(JsPath \ "description").write[String]
)(unlift(Product.unapply))
这似乎行不通,因为需要使用所有 fields/attributes unapply 方法 returns。
有没有办法让第二种序列化方法只适用于我想要序列化的属性,或者我必须使用这样的方法:
implicit object ProductWrites extends Writes[Product] {
def writes(p: Product) = Json.obj(
"name" -> Json.toJson(p.name),
"description" -> Json.toJson(p.description)
)
}
这是唯一的方法吗?
我认为你的最后一个例子是可行的。这是使用隐式 val 而不是隐式对象做同样事情的另一种方法:
implicit val productWrites: Writes[Product] = Writes { p =>
Json.obj(
"name" -> Json.toJson(p.name),
"description" -> Json.toJson(p.description)
)
}
unlift(Product.unapply)
具有类型 Product => (Long, String, String)
。
在这种情况下,参数的类型应为 Product => (String, String)
。你可以像下面这样写一个函数文字。
implicit val productWrites: Writes[Product] = (
(JsPath \ "name").write[String] and
(JsPath \ "description").write[String]
)(p => (p.name, p.description))
假设我有这样一个案例 class:
case class Product(ean: Long, name: String, description: String)
我想将这个 class 的对象序列化为 Json,我可以像这样实现 Writes 特性:
implicit val productWrites: Writes[Product] = (
(JsPath \ "ean").write[Long] and
(JsPath \ "name").write[String] and
(JsPath \ "description").write[String]
)(unlift(Product.unapply))
如果我想序列化对象的所有属性,这很好用。现在假设我不想序列化 ean
。我试过这样的事情:
implicit val productWrites: Writes[Product] = (
(JsPath \ "name").write[String] and
(JsPath \ "description").write[String]
)(unlift(Product.unapply))
这似乎行不通,因为需要使用所有 fields/attributes unapply 方法 returns。
有没有办法让第二种序列化方法只适用于我想要序列化的属性,或者我必须使用这样的方法:
implicit object ProductWrites extends Writes[Product] {
def writes(p: Product) = Json.obj(
"name" -> Json.toJson(p.name),
"description" -> Json.toJson(p.description)
)
}
这是唯一的方法吗?
我认为你的最后一个例子是可行的。这是使用隐式 val 而不是隐式对象做同样事情的另一种方法:
implicit val productWrites: Writes[Product] = Writes { p =>
Json.obj(
"name" -> Json.toJson(p.name),
"description" -> Json.toJson(p.description)
)
}
unlift(Product.unapply)
具有类型 Product => (Long, String, String)
。
在这种情况下,参数的类型应为 Product => (String, String)
。你可以像下面这样写一个函数文字。
implicit val productWrites: Writes[Product] = (
(JsPath \ "name").write[String] and
(JsPath \ "description").write[String]
)(p => (p.name, p.description))