spray-json for normal classes (non case) on a List
Asked Answered
D

2

6

I'm finding myself in a situation in which I need to serialize into JSON a non case class.

Having a class as:

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

I've created a JsonProtocol for this class:

object MyClassJsonProtocol extends DefaultJsonProtocol {

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

Later on in the code I import the protocol..

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

val json = aListOfMyClasses.toJson

When trying to build the project I get the following error:

Cannot find JsonWriter or JsonFormat for type class List[MyClass]

spray-json has already a format for generic list and I'm providing a format for my class, what would be the problem?

Thanks in advance...!!!

Darill answered 28/10, 2014 at 17:0 Comment(0)
E
3

When I extended MyClassJsonFormat from JsonFormat instead of JsonWriter, it stared working fine. Looks like the CollectionFormats trait will work only if you extend from JsonFormat

The following code compiles fine for 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])
    }
  }
Estate answered 29/10, 2014 at 9:39 Comment(4)
Thks. It works, though I still don't know why CollectionFormats trait is not included. I added it to the imports explicitly but would compile ether.Darill
No need to import CollectionFormats. DefaultJsonProtocol extends all these traits - github.com/spray/spray-json/blob/master/src/main/scala/spray/…Estate
I know, but then it doesn't explain why it's not working when extending JsonWriter instead of JsonFormat. Is still extending DefaultJsonProtocol.Darill
I have this same behavior - making a Writer didn't effect anything. Changing to Format does. I wonder what's going on behind the scenes - is this a bug (in spray.json)? Annoying since I also need the Reader and now I have to figure out a way to get the default reader invoked, via my format.Lather
L
0

The reason seems to be mentioned 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.

You and I have run into this. I don't see other way out at the moment than @user007's suggestion to use a full JsonFormat. That, itself, brings more difficulties at least to me - I was planning to use the default reader for my class.

Oh, well...

Lather answered 6/7, 2015 at 12:37 Comment(2)
I would suggest you to use json4s. It will make your life way easier. At least that's what I ended up doing. No regrets at all.Darill
Thanks for the suggestion, but I'm rather pleased with spray-json, otherwise.Lather

© 2022 - 2024 — McMap. All rights reserved.