Spray 不会将我的案例类转换为 json 并期待一个 spray.httpx.marshalling.ToResponseMarshallable

Posted

技术标签:

【中文标题】Spray 不会将我的案例类转换为 json 并期待一个 spray.httpx.marshalling.ToResponseMarshallable【英文标题】:Spray won't convert my case class to json and expect a spray.httpx.marshalling.ToResponseMarshallable 【发布时间】:2014-09-02 11:50:28 【问题描述】:

我正在尝试重新处理 this 或 this,但我不断收到无法修复的错误...

首先,这是我的依赖项:

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'

现在我想做的是:

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)

与:

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

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

现在我收到此错误:

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

我尝试了很多东西,但无法让它发挥作用。 我试过了

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

最后我做的是

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

这可行,但是当我需要 application/json 时,它会作为 Content-Type: text/plain 发送给客户端。

有人知道这里有什么问题吗?

编辑:我在github上添加了一个示例项目https://github.com/ydemartino/spray-test

【问题讨论】:

+1。这是一篇很棒的第一篇文章,欢迎关注 SO :D 我应该在***评论中问这个问题。您使用的是哪个版本的 Scala?看起来 Spray 还没有发布 2.11 github.com/spray/spray/issues/790 我看到了这个问题,但是根据官方文档:spray.io/project-info/current-versions "spray 1.3.1 是针对 Scala 2.10.3 和 Akka 2.3.0 以及 Scala 2.11.1 和 Akka 2.3 构建的.2。”因为我可以使用 'io.spray:spray-can_2.11:1.3.1' 获取文件,所以我认为他们同时修复了它。我将尝试使用 scala 2.10 来查看我的代码是否可以编译。 我在 github 上添加了一个示例项目,可以重现问题。本项目使用 scala 2.10:github.com/ydemartino/spray-test 【参考方案1】:

将您的模型移出 json 协议并使其成为常规对象(而不是案例对象)

case class Answer(code: Int, content: String)

object MasterJsonProtocol extends DefaultJsonProtocol 
  implicit val anwserFormat = jsonFormat2(Answer)

编辑

同时清理你的导入:

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 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)

【讨论】:

嘿,谢谢你的回答,我照你说的做了,把它变成一个对象(我实际上没有注意到它是一个案例对象),用 SprayJsonSupport 删除并将模型移到外面但我我得到了完全相同的错误。 嘿,我尝试清理进口。一样。我的 IDE 将它们中的两个灰显为“未使用的导入语句”,我是否缺少使其工作的依赖项? 你使用的是什么版本的 Scala? Scala 版本 2.11.1 和 jdk 1.8.05。我切换到 jdk 1.7.60 来检查 java 是否弄乱了我的构建,但我得到了相同的结果。【参考方案2】:

我创建了一个拉取请求来解决您的问题:https://github.com/ydemartino/spray-test/pull/1

必须先声明 json 协议对象,然后才能隐式使用它。我不完全确定为什么编译器无法弄清楚,但是将对象声明移到顶部修复了它。

对于您的实际项目,请确保在每个文件中声明包,然后在导入语句中使用这些包。

【讨论】:

哇,谢谢!我也无法弄清楚为什么我们必须在之前声明它......无论如何,scala版本存在问题,我尝试使用相同的代码将依赖项更改为2.11,但它无法编译之前出现的错误...... 【参考方案3】:

在我的例子中,无法解析的隐式格式实例的名称与本地定义冲突,因此它被隐藏了。编译器对此保持沉默。经过数小时的头部撞击后才偶然发现。

【讨论】:

以上是关于Spray 不会将我的案例类转换为 json 并期待一个 spray.httpx.marshalling.ToResponseMarshallable的主要内容,如果未能解决你的问题,请参考以下文章

spray-json 找不到 List[T] 类型的 JsonReader

Spray-json 和列表编组

Scala,spray-json:通用枚举 json 格式

如何使用 scala 和 json spray 将混合类型值的 json 转换为 json

如何将我的类对象转换为 JSON for Alamofire

使用 Spray-json 解析简单数组