【问题标题】:Can I return Future[Option[Foo]] in spray?我可以在喷雾中返回 Future[Option[Foo]] 吗?
【发布时间】:2014-02-23 15:37:22
【问题描述】:

到目前为止,我的尝试遇到了java.lang.ClassCastException: scala.runtime.BoxedUnit cannot be cast to scala.Option。事实上,我什至无法想象适当的反应会是什么样子。有可能吗?

【问题讨论】:

  • 你能显示你得到BoxedUnit异常的代码吗?似乎您没有返回应该返回选项值的位置。

标签: scala rest spray


【解决方案1】:

这里可能有两种选择:要么是程序中的错误,要么您没有提供任何方式来编组您的 Foo 类型,因为默认情况下会处理 FutureOption。例如,这条路线可以由标准喷雾编组器处理,没有任何问题:

val route = {
  (get & path("test")) {
    complete {
      Future(Option("Hello Spray!"))
    }
  }
}

现在,如果您在 /test 上发出 GET 请求,您将得到正确的响应。

如果你有一个特定的类型,那么你需要提供你自己的 ToResponseMarshallable 类型的编组器来通过隐式上下文进行搜索。我认为最常见和最简单的方法是做出 Json 响应,为此您需要一个 spray-json(或其他一些受支持的 json lib),并且只需提供一个 json 转换器,例如:

import spray.json.DefaultJsonProtocol._

case class Boy(name: String, age: String)
object Boy {
  implicit val boyJson = jsonFormat2(Boy.apply)
}

现在唯一要做的就是将一个 json marshaller 放入作用域中:

import spray.httpx.SprayJsonSupport._ // import json marshaller

val route = {
  (get & path("test") {
    complete {  
      Future(Option(Boy("Name", 0)))
    }
  }
}

现在您将收到 json 响应。如果您需要其他类型的响应,请为 Boy 类型制作自定义编组器。

【讨论】:

  • @4lex1v 复制和粘贴您的示例会导致这种类型不匹配:expected: ToResponseMarshallable, actual: Future[Option[TestRoute.this.Boy]]。 TestRoute 是这个 route 存在的特征。自 2014 年以来,要求是否发生变化以使其工作?
【解决方案2】:

简而言之 - 是的,但您需要让编译器满意。

Spray 允许您返回 Future 或简单的响应,只要它可以编组回响应即可。您需要确保在为您进行编组的范围内有隐式转换或显式转换您的 Foo 对象。

以下是执行响应转换的方式:http://spray.io/documentation/1.2.0/spray-httpx/response-transformation/

【讨论】:

    【解决方案3】:

    对于在完整块中返回未来仍然遇到问题的任何人,请确保在范围内具有诸如 scala.concurrent.ExecutionContext.Implicits.global 之类的执行上下文! IDE 往往不明白这是问题所在,可能会让您陷入漫长的兔子洞。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-02
      • 2016-08-01
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2016-06-15
      相关资源
      最近更新 更多