Search code examples
scalasprayspray-json

Spray won't convert my case class to json and expect a spray.httpx.marshalling.ToResponseMarshallable


I'm trying to reprocude this or this, but I keep getting an error I am not able to fix...

First of all, here are my dependencies:

compile 'io.spray:spray-can_2.11:1.3.1'
compile 'io.spray:spray-routing_2.11:1.3.1',
compile 'io.spray:spray-json_2.11:1.2.6'

Now what I'm trying to do is:

class WHttpService extends Actor with HttpService with ActorLogging {

  implicit def actorRefFactory = context

  def receive = runRoute(route)

  lazy val route = logRequest(showReq _) {
    // Way too much imports but I tried all I could find
    import spray.json._
    import DefaultJsonProtocol._
    import MasterJsonProtocol._
    import spray.httpx.SprayJsonSupport._
    path("server" / Segment / DoubleNumber / DoubleNumber) { (login, first, second) =>
      get {
          complete {
            Answer(1, "test")
          }
      }
    }
  }

  private def showReq(req : HttpRequest) = LogEntry(req.uri, InfoLevel)
}

With:

case object MasterJsonProtocol extends DefaultJsonProtocol with SprayJsonSupport {
  import spray.json._

  case class Answer(code: Int, content: String)
  implicit val anwserFormat: JsonFormat[Answer] = jsonFormat2(Answer)
}

Now I get this error:

Error:(42, 19) type mismatch;
 found   : MasterJsonProtocol.Answer
 required: spray.httpx.marshalling.ToResponseMarshallable
            Answer(1, "test")
                  ^

I tried a lot of things but can't manage to make it works. I tried with

Answer(1, "test").toJson
Answer(1, "test").toJson.asJsObject

Finally what I did was

complete {
    Answer(1, "test").toJson.compactPrint
}

This works but it is sent to the client as Content-Type: text/plain when I need application/json.

Anyone see what the problem is here?

Edit: I added a sample project on github https://github.com/ydemartino/spray-test


Solution

  • I created a pull request to fix your problem: https://github.com/ydemartino/spray-test/pull/1

    The json protocol object has to be declared before it can be used implicitly. I'm not wholly sure why the compiler can't figure it out, but moving the object declaration to the top fixed it.

    For your actual project make sure to declare packages in each file then use those packages to in the import statements.