2014-10-28 13 views
6

Mi trovo in una situazione in cui ho bisogno di serializzare in JSON una classe non-case.spray-json per classi normali (non case) su una lista

Avendo una classe come:

class MyClass(val name: String) { 
    def SaySomething() : String = { 
    return "Saying something... " 
    } 
} 

Ho creato un JsonProtocol per questa classe:

object MyClassJsonProtocol extends DefaultJsonProtocol { 

    implicit object MyClassJsonFormat extends JsonWriter[MyClass] { 
    override def write(obj: MyClass): JsValue = 
    JsObject(
     "name" -> JsString(obj.name) 
    ) 
    } 
} 

Più tardi nel codice importare il protocollo ..

val aListOfMyClasses = List[MyClass]() ... // lets assume that has items and not an empty list 
import spray.json._ 
import MyClassJsonProtocol._ 

val json = aListOfMyClasses.toJson 

Quando provo a costruire il progetto, ottengo il seguente errore:

Non riesci a trovare JsonWriter o JsonFormat per il tipo di classe List [MyClass]

spray-JSON ha già un formato per elenco generico e sto fornendo un formato per la mia classe, quale sarebbe il problema?

Grazie in anticipo ... !!!

risposta

3

Quando ho esteso MyClassJsonFormat da JsonFormat invece di JsonWriter, si fissarono lavorando bene. Sembra che il tratto CollectionFormats funziona solo se si estende da JsonFormat

Il seguente codice compila bene per me

object MyClassJsonProtocol extends DefaultJsonProtocol { 

    implicit object MyClassJsonFormat extends JsonFormat[MyClass] { 
    override def write(obj: MyClass): JsValue = 
     JsObject(
     "name" -> JsString(obj.name) 
    ) 

     override def read(json: JsValue): MyClass = new MyClass(json.convertTo[String]) 
    } 
    } 
+0

Thks. Funziona, anche se non so ancora perché il tratto CollectionFormats non sia incluso. L'ho aggiunto alle importazioni esplicitamente, ma avrei compilato l'etere. – leonfs

+0

Non è necessario importare CollectionFormats. DefaultJsonProtocol estende tutti questi tratti - https://github.com/spray/spray-json/blob/master/src/main/scala/spray/json/DefaultJsonProtocol.scala#L26 –

+0

Lo so, ma poi non spiega perché non funziona quando si estende JsonWriter anziché JsonFormat. Sta ancora estendendo DefaultJsonProtocol. – leonfs

0

Il motivo sembra essere menzionati here:

An issue you might run into with just JsonReader/JsonWriter is that when you try to lookup JsonReader/JsonWriter for Option or a collection, it looks for a JsonFormat for the contained type, which will fail. Not sure if there is something I am missing that will fix that issue.

Tu e Ho incontrato questo. Al momento non vedo altra via d'uscita del suggerimento di @ user007 di utilizzare un intero JsonFormat. Questo, di per sé, porta almeno più difficoltà almeno a me: stavo progettando di usare il lettore predefinito per la mia classe.

Oh, beh ...

+0

Ti suggerisco di usare json4s. Renderà la tua vita più facile. Almeno questo è quello che ho finito per fare. Nessun rimpianto. – leonfs

+0

Grazie per il suggerimento, ma sono piuttosto soddisfatto di spray-json, altrimenti. – akauppi