我正在尝试使用play-json读取将以下Json转换为结果案例类。但是,我坚持使用语法将经度和纬度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))
答案 0 :(得分:1)
从根本上说,Reads[T]
只需要一个将元组转换为T
实例的函数。因此,您可以为Point
类编写一个,给定location
JSON对象,如下所示:
implicit val pointReads: Reads[Point] = (
(__ \ "latitude").read[Double] and
(__ \ "longitude").read[Double]
)((lat, lng) => new GeometryFactory().createPoint(new Coordinate(lat, lng))
然后将其与BusinessInput
类的其余数据结合使用:
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
类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 _)