从多个Json字段创建单个子字段,并使用Play-json应用于生成的Object

时间:2017-08-25 23:07:11

标签: scala playframework playframework-2.0 play-json

我正在尝试使用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))

1 个答案:

答案 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 _)

在第二种情况下,我们使用BusinessInputapply方法作为捷径,但您可以轻松地使用(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 _)