【问题标题】:spray Collection ToResponseMarshallablespray Collection ToResponseMarshallable
【发布时间】:2015-04-18 22:48:00
【问题描述】:

我正在尝试从喷雾路由中的完整指令中返回一个列表。

complete {
  List("hello")
}

但是,我收到一个错误 -

Expression of type List[String] doesn't conform to expected type ToResponseMarshallable

我在使用 Seq 时遇到了同样的错误。我看到在 spray-httpx documentation 中默认不提供 List 和 Seq 的编组器。但是,spray-json 在其 DefaultJsonProtocol 中提供了编组支持。我已经在我的代码中导入了 spray.httpx.SprayJsonSupport._ 和 spray.json.DefaultJsonProtocol._ ,但这也没有帮助。

知道如何使用 spray-json 编组 List/Seq 吗?还是我必须编写自己的 Marshaller?

(我的scala版本是2.11.4)

【问题讨论】:

    标签: scala scala-collections spray spray-json


    【解决方案1】:

    使用spray 1.3.2 和spray-json 1.3.2 应该是可能的。

    确保你导入(虽然你说你这样做,但仔细检查)。

    import spray.httpx.SprayJsonSupport._
    import spray.json.DefaultJsonProtocol._
    

    考虑以下示例:

    import akka.actor.{ActorSystem, Props, Actor}
    import akka.io.IO
    import spray.can.Http
    import spray.routing.HttpService
    import akka.pattern.ask
    import akka.util.Timeout
    import scala.concurrent.duration._
    import spray.httpx.SprayJsonSupport._
    import spray.json.DefaultJsonProtocol._
    
    object Boot extends App {
      implicit val system = ActorSystem("so")
    
      val testActor = system.actorOf(Props[TestActor])
    
      implicit val timeout = Timeout(5.seconds)
      IO(Http) ? Http.Bind(testActor, interface = "0.0.0.0", port = 5000)
    
    }
    
    class TestActor extends Actor with HttpService {
    
      def receive  = runRoute(route)
    
      def actorRefFactory = context
    
      val route = get{
        path("ping") {
          complete(List("OK"))
        }
      }
    
    }
    

    请求/ping 返回["OK"],看起来没问题。

    仅供参考build.sbt下面。

    build.sbt

    val akkaVersion = "2.3.5"
    
    val sprayVersion = "1.3.2"
    
    resolvers += "spray" at "http://repo.spray.io/"
    
    scalaVersion := "2.11.5"
    
    scalacOptions := Seq("-feature", "-unchecked", "-deprecation", "-encoding", "utf8")
    
    libraryDependencies ++= Seq(
      "com.typesafe.akka"   %% "akka-actor"       % akkaVersion,
      "io.spray"            %% "spray-can"        % sprayVersion,
      "io.spray"            %% "spray-routing"    % sprayVersion,
      "io.spray"            %% "spray-client"     % sprayVersion,
      "io.spray"            %% "spray-json"       % "1.3.1"
    )
    

    【讨论】:

    • 是的,这行得通。但是如果我用大括号替换括号,它就会失败。我正在完成 {List("OK")}。我的实际场景需要一个代码块。你知道为什么使用大括号可能会失败吗?
    • 在我的示例中,当我将( 替换为{ 并将) 替换为} 时,它有效,所以你确定这是你所做的唯一更改吗?
    • 好的。我认为只是 IntelliJ 快疯了。当我构建并运行我的项目时,它工作正常。谢谢!
    【解决方案2】:

    akka 2.3.5 以来,编组API 似乎发生了变化。对于akka-2.4.11.2SprayJsonSupport 需要import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._

    1) 以下是工作 sbt,

    name := "some-project"
    
    version := "1.0"
    
    scalaVersion := "2.11.5"
    
    scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8")
    
    val akkaVersion = "2.4.5"
    
    libraryDependencies ++= {
      Seq(
        "com.typesafe.akka" %% "akka-http-experimental" % akkaVersion,
        "com.typesafe.akka" % "akka-http-spray-json-experimental_2.11" % akkaVersion,
        "com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
    
        "org.mongodb" % "mongo-java-driver" % "3.4.1",
        "org.apache.kafka" %% "kafka" % "0.10.1.1",
        "org.apache.kafka" % "kafka-clients" % "0.10.1.1",
    
        //test
        "org.scalatest" %% "scalatest" % "2.2.5" % "test",
        "com.typesafe.akka" %% "akka-http-testkit" % "10.0.9" % "test",
        "de.flapdoodle.embed" % "de.flapdoodle.embed.mongo" % "2.0.0" % "test"
      )
    }
    
    parallelExecution in Test := false
    

    2) 进口是,

    import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
    import spray.json.DefaultJsonProtocol._
    
    object GetMusicResources {
    
      val music_get_api =
        path("music") {
          get {
            complete {
              List("my data1")
            }
          }
        }
    }
    

    3) 测试

      Get("/music") ~> GetMusicResources.music_get_api ~> check {
        val response1: Future[ByteString] = response.entity.toStrict(300.millis).map {_.data }
    
        response1.map(_.utf8String).map { responseString =>
          responseString shouldBe """["my data1"]"""
        }
    
      }
    

    【讨论】:

      【解决方案3】:

      就我而言,我错过了第二次导入:

      import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
      import spray.json.DefaultJsonProtocol._  // <= this one
      

      万一有人遇到同样的问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        • 2015-07-26
        相关资源
        最近更新 更多