2017-08-25 2 views
0

Ich versuche ein play-json reads zu verwenden, um das folgende Json in eine resultierende Fallklasse umzuwandeln. Ich bin jedoch auf die Syntax zum Konvertieren der Längen-und Breitengrad Json-Werte in ein Point-Objekt stecken unter der Zwischenzeit den Rest der Json-Werte in die gleichen resultierenden BusinessInput-Objekt konvertieren. Ist das syntaktisch möglich?Erstelle ein einzelnes Unterfeld aus mehreren Json-Feldern und wende das Ergebnis mit Play-json an

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)) 

Antwort

1

Grundsätzlich ein Reads[T] erfordert nur eine Funktion, die einen Tupels in einer Instanz von T dreht. Sie können also eine für Ihre Point Klasse schreiben, da location JSON-Objekt, etwa so:

implicit val pointReads: Reads[Point] = (
    (__ \ "latitude").read[Double] and 
    (__ \ "longitude").read[Double]  
)((lat, lng) => new GeometryFactory().createPoint(new Coordinate(lat, lng)) 

und dann mit dem Rest Ihrer Daten für die BusinessInput Klasse kombinieren, dass:

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

In der zweiten Fall verwenden wir die BusinessInput Klassen apply Methode als Abkürzung, aber Sie könnten genauso einfach ein Tupel von (userId, name, point) nehmen und eins mit den optionalen Feldern erstellen, die weggelassen werden.

Wenn Sie nicht über ein Point liest separat vornehmen wollen, kombinieren sie nur die gleichen Prinzipien mit:

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 _) 
Verwandte Themen