Je travaille avec Play JSON API (dernière version; Play 2.4), lisant le JSON entrant dans des objets.

Lorsque vous écrivez JSON, il n'y a absolument aucun problème à utiliser une liste d'objets personnalisés , tant que je l'ai implicit val writes = Json.writes[CustomType].

Mais apparemment l'inverse n'est pas vrai, car ce qui suit ne fonctionne pas même si Reads est généré à la fois pour le type de niveau supérieur et le type d'élément de liste (en utilisant Json.reads[Incoming] et Json.reads[Item]). La mise en œuvre Reads personnalisée est-elle obligatoire? Ou est-ce que je rate quelque chose d'évident? Quelle est la manière la plus simple de faire fonctionner cela?

Exemple simplifié:

JSON:

{
  "test": "...",
  "items": [
     { "id": 44, "time": "2015-11-20T11:04:03.544" },
     { "id": 45, "time": "2015-11-20T11:10:10.101" }
  ]
}

Modèles / DTO correspondant aux données entrantes:

import play.api.libs.json.Json

case class Incoming(test: String, items: List[Item])

object Incoming {
  implicit val reads = Json.reads[Incoming]
}


case class Item(id: Long, time: String)

object Item {
  implicit val reads = Json.reads[Item]
}

Manette:

def test() = Action(parse.json) { request =>
  request.body.validate[Incoming].map(incoming => {
     // ... handle valid incoming data ...
  }).getOrElse(BadRequest)
}

Le compilateur a ceci à dire:

No implicit format for List[models.Item] available.
[error]   implicit val reads = Json.reads[Incoming]
                       ^
No Json deserializer found for type models.Incoming. 
Try to implement an implicit Reads or Format for this type.
[error]     request.body.validate[Incoming].map(incoming => {
1
Jonik 5 janv. 2016 à 18:41

2 réponses

Meilleure réponse

Essayez de définir la classe de cas et l'objet pour Item avant ceux pour Incoming. Pour plus d'informations, consultez cette réponse: https://stackoverflow.com/a/15705581

3
Community 23 mai 2017 à 12:31

Le problème peut provenir de vos importations dans Controller. Importer simplement "Incoming" importera la classe de cas. Pour importer le val implicite, essayez "Incoming._". Cela importera tous les membres de l'objet entrant.

1
ValSmith 5 janv. 2016 à 16:23