从多个 Json 字段创建单个子字段并使用 Play-json 应用于生成的对象
Create Single sub Field from multiple Json Fields and apply to resulting Object using Play-json
我正在尝试使用 play-json 读取将以下 Json 转换为结果案例 class。但是,我坚持使用语法将经度和纬度 json 值转换为 Point 对象,同时将其余 json 值转换为相同的结果 BusinessInput 对象。
这在语法上可能吗?
case class BusinessInput(userId: String, name: String, location: Point, address: Option[String], phonenumber: Option[String], email: Option[String])
object BusinessInput {
implicit val BusinessInputReads: Reads[BusinessInput] = (
(__ \ "userId").read[String] and
(__ \ "location" \ "latitude").read[Double] and
(__ \ "location" \ "longitude").read[Double]
)(latitude: Double, longitude: Double) => new GeometryFactory().createPoint(new Coordinate(latitude, longitude))
从根本上说,Reads[T]
只需要一个将元组转换为 T
实例的函数。因此,给定 location
JSON 对象,您可以为 Point
class 编写一个,如下所示:
implicit val pointReads: Reads[Point] = (
(__ \ "latitude").read[Double] and
(__ \ "longitude").read[Double]
)((lat, lng) => new GeometryFactory().createPoint(new Coordinate(lat, lng))
然后将其与 BusinessInput
class:
的其余数据合并
implicit val BusinessInputReads: Reads[BusinessInput] = (
(__ \ "userId").read[String] and
(__ \ "name").read[String] and
(__ \ "location").read[Point] and
(__ \ "address").readNullable[String] and
(__ \ "phonenumber").readNullable[String] and
(__ \ "email").readNullable[String]
)(BusinessInput.apply _)
在第二种情况下,我们使用 BusinessInput
classes apply
方法作为捷径,但您可以轻松地使用 (userId, name, point)
和创建一个省略了可选字段的字段。
如果您不想 Point
单独阅读,只需使用相同的原则将它们组合起来:
implicit val BusinessInputReads: Reads[BusinessInput] = (
(__ \ "userId").read[String] and
(__ \ "name").read[String] and
(__ \ "location").read[Point]((
(__ \ "latitude").read[Double] and
(__ \ "longitude").read[Double]
)((lat, lng) => new GeometryFactory().createPoint(new Coordinate(lat, lng)))) and
(__ \ "address").readNullable[String] and
(__ \ "phonenumber").readNullable[String] and
(__ \ "email").readNullable[String]
)(BusinessInput.apply _)
我正在尝试使用 play-json 读取将以下 Json 转换为结果案例 class。但是,我坚持使用语法将经度和纬度 json 值转换为 Point 对象,同时将其余 json 值转换为相同的结果 BusinessInput 对象。 这在语法上可能吗?
case class BusinessInput(userId: String, name: String, location: Point, address: Option[String], phonenumber: Option[String], email: Option[String])
object BusinessInput {
implicit val BusinessInputReads: Reads[BusinessInput] = (
(__ \ "userId").read[String] and
(__ \ "location" \ "latitude").read[Double] and
(__ \ "location" \ "longitude").read[Double]
)(latitude: Double, longitude: Double) => new GeometryFactory().createPoint(new Coordinate(latitude, longitude))
从根本上说,Reads[T]
只需要一个将元组转换为 T
实例的函数。因此,给定 location
JSON 对象,您可以为 Point
class 编写一个,如下所示:
implicit val pointReads: Reads[Point] = (
(__ \ "latitude").read[Double] and
(__ \ "longitude").read[Double]
)((lat, lng) => new GeometryFactory().createPoint(new Coordinate(lat, lng))
然后将其与 BusinessInput
class:
implicit val BusinessInputReads: Reads[BusinessInput] = (
(__ \ "userId").read[String] and
(__ \ "name").read[String] and
(__ \ "location").read[Point] and
(__ \ "address").readNullable[String] and
(__ \ "phonenumber").readNullable[String] and
(__ \ "email").readNullable[String]
)(BusinessInput.apply _)
在第二种情况下,我们使用 BusinessInput
classes apply
方法作为捷径,但您可以轻松地使用 (userId, name, point)
和创建一个省略了可选字段的字段。
如果您不想 Point
单独阅读,只需使用相同的原则将它们组合起来:
implicit val BusinessInputReads: Reads[BusinessInput] = (
(__ \ "userId").read[String] and
(__ \ "name").read[String] and
(__ \ "location").read[Point]((
(__ \ "latitude").read[Double] and
(__ \ "longitude").read[Double]
)((lat, lng) => new GeometryFactory().createPoint(new Coordinate(lat, lng)))) and
(__ \ "address").readNullable[String] and
(__ \ "phonenumber").readNullable[String] and
(__ \ "email").readNullable[String]
)(BusinessInput.apply _)