我有一个看起来像这样的代码。
import akka.actor.{Props, ActorRef, Actor}
import akka.util.Timeout
import org.json4s.DefaultFormats
import spray.routing.HttpService
import spray.httpx.Json4sSupport
import scala.concurrent.Await
import scala.concurrent.duration._
import akka.pattern.ask
/**
* Created by mihaildoronin on 06.10.15.
*/
class ProcessesService() extends Actor with HttpService {
def actorRefFactory = context
def receive = runRoute(route)
val systemActor = context.actorOf(Props[SystemActor])
implicit val json4sFormats = DefaultFormats
implicit val timeout = Timeout(5 seconds)
val route = path("processes") {
get {
parameters('fromId.as[Int], 'count.as[Int]).as(GetProcessesCommand) { command =>
complete {
val response = Await.result(systemActor ? command, timeout.duration).asInstanceOf[CursoredResponse]
response
}
}
} ~
post {
entity(as[RegisterProcessCommand]) { command =>
complete {
val result = Await.result(systemActor ? command, timeout.duration).asInstanceOf[Long]
}
}
}
} ~
pathPrefix("processes" / IntNumber) { id =>
complete {
val process = Await.result(systemActor ? GetProcessCommand(id), timeout.duration).asInstanceOf[Process]
process
}
}
}
它给了我这样的错误
Error:(28, 11) type mismatch;
found : CursoredResponse
required: spray.httpx.marshalling.ToResponseMarshallable
response
^
但在这个tutorial中,类似的代码似乎有效。我已经覆盖了json4sFormats并使它们隐含,我使用了案例类,我在这里缺少什么? 我是scala和spray的新手,所以我不清楚。
答案 0 :(得分:2)
对于你的课程,你应该提供Marshaller和Unmarshaller。来自Spray Json教程:
import spray.json.DefaultJsonProtocol
import spray.httpx.unmarshalling._
import spray.httpx.marshalling._
并将你的CursoredResponse投给Json
import MyJsonProtocol._
import spray.httpx.SprayJsonSupport._
import spray.util._
object CursoredResponseProtocol extends DefaultJsonProtocol {
implicit val CursoredResponseFormat = jsonFormat3(CursoredResponse)
}
这里是reference:
答案 1 :(得分:0)
我认为你只需要将spray.httpx.Json4sSupport混合到你的类中。所以......
class ProcessesService() extends Actor with HttpService with Json4sSupport {
...
}
我最初提供了一个使用spray-json方法的通用答案。但重新阅读后,我意识到我正在回答错误的问题。我会在下面留下原来的答案,万一有人碰巧发现它有用。
我首选的方法是创建一个扩展Spray的DefaultJsonProtocol和SprayJsonSupport的特征。在其中,我为所有案例类创建对RootJsonFormats的隐式引用。然后我只是将该特征混合到我的路线定义的类或特征中。
对我来说,这是保持组织有序的最简单方法,并为我的Spray路由以及我使用Spray客户端与基于HTTP的服务提供商集成的其他组件提供所需的(联合)编组功能生成和使用JSON。
假设您有一个返回FooBar的端点。这是我们要编组给JSON的案例类:
case class FooBar(withNuts: Boolean = true, kingSize: Boolean = false)
我们定义一个特性,它包含我们自定义类的RootJsonFormat - 在本例中是一个FooBar - 它将能够读写JSON
import spray.json.{RootJsonFormat, DefaultJsonProtocol}
import spray.httpx.SprayJsonSupport
trait MyAppJsonProtocol extends DefaultJsonProtocol with SprayJsonSupport {
implicit val FooBarFormat: RootJsonFormat[FooBar] = jsonFormat2(FooBar)
}
然后将MyAppJsonProtocol混合到路线中。
trait FooBarRoute extends HttpService with MyAppJsonProtocol {
implicit def executionContext = actorRefFactory.dispatcher
val fooRoute = {
(get & path("foobar")) {
complete(FooBar())
}
}
}
如果你有其他需要(un)封送的类,只需为MyAppJsonProtocol特性中的每个类添加另一个隐式RootJsonFormat。