Создайте одно подполе из нескольких полей Json и примените к полученному объекту с помощью Play-json

Я пытаюсь использовать play-json для преобразования следующего Json в результирующий класс case. Однако я застрял в синтаксисе для преобразования значений 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 ответ

Решение

Принципиально, 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 _)
Другие вопросы по тегам