15

Próbuję serializować niektóre stosunkowo proste modele w json. Na przykład, chciałbym, aby uzyskać reprezentację JSON:serializowanie obiektów do json z play.api.libs.json

case class User(val id: Long, val firstName: String, val lastName: String, val email: Option[String]) { 
    def this() = this(0, "","", Some("")) 
} 

Czy muszę napisać własny Format [Użytkownik] z odpowiednim odczytuje i zapisuje metod czy jest jakiś inny sposób? Spoglądałem na https://github.com/playframework/Play20/wiki/Scalajson, ale wciąż jestem trochę zagubiony.

Odpowiedz

22

Tak, napisanie własnej instancji Format to the recommended approach. Biorąc pod uwagę następujące klasy, na przykład:

case class User(
    id: Long, 
    firstName: String, 
    lastName: String, 
    email: Option[String] 
) { 
    def this() = this(0, "","", Some("")) 
} 

Instancja może wyglądać następująco:

import play.api.libs.json._ 

implicit object UserFormat extends Format[User] { 
    def reads(json: JsValue) = User(
    (json \ "id").as[Long], 
    (json \ "firstName").as[String], 
    (json \ "lastName").as[String], 
    (json \ "email").as[Option[String]] 
) 

    def writes(user: User) = JsObject(Seq(
    "id" -> JsNumber(user.id), 
    "firstName" -> JsString(user.firstName), 
    "lastName" -> JsString(user.lastName), 
    "email" -> Json.toJson(user.email) 
)) 
} 

I chcesz go używać tak:

scala> User(1L, "Some", "Person", Some("[email protected]")) 
res0: User = User(1,Some,Person,Some([email protected])) 

scala> Json.toJson(res0) 
res1: play.api.libs.json.JsValue = {"id":1,"firstName":"Some","lastName":"Person","email":"[email protected]"} 

scala> res1.as[User] 
res2: User = User(1,Some,Person,Some([email protected])) 

Zobacz the documentation aby uzyskać więcej informacji .

+0

Znakomity, dzięki! A co jeśli chciałbym Seq [User] jako Json? :) – LuxuryMode

+0

Gra jest dostarczana z instancją 'Seq', więc możesz po prostu użyć' Json.toJson (users) .as [Seq [User]] '. –

+0

Używając "JsNumber" Play z Mongo, pojawia się błąd serializacji: '[błąd] play - Nie można wywołać akcji, w końcu dostałem błąd: java.lang.IllegalArgumentException: nie można serializować klasy scala.math.BigDecimal' –

6

Dzięki temu użytkownik jest klasa przypadek można też zrobić coś takiego:

implicit val userImplicitWrites = Json.writes[User] 
val jsUserValue = Json.toJson(userObject) 

bez pisania własnych Format [Użytkownik]. Można zrobić to samo z brzmi:

implicit val userImplicitReads = Json.reads[User] 

nie znalazłem go w docs, tu jest link do API: http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.libs.json.Json $

+0

Tylko dla kompletności - bez użycia implikacji: 'Json.reads [Użytkownik] .reads (myJson) .get' – Ixx

+0

Ten powinien być teraz oznaczony jako odpowiedź. Oto link do zaktualizowanego dokumentu: https://www.playframework.com/documentation/2.5.x/ScalaJsonAutomated –