Создайте одно подполе из нескольких полей 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 _)