为什么 mapTo 在 Akka HTTP 客户端中失败?

Why does mapTo fail in Akka HTTP client?

我有一个Akka HTTP服务,其中returns一个字符串,如下图:

val route1: Route = {
    path("hello") {
      get{
        complete{
          println("Inside r1")
          "You just accessed hello"
        }
      }
   }
}

我有一个尝试访问此路由的 Akka HTTP 客户端。但是下面的代码失败了:

  val future1 = Http()
    .singleRequest(
      HttpRequest(method = HttpMethods.GET,
        uri = "http://localhost:8187/hello")).mapTo[String]

  future1.onSuccess({
    case y:String=>println(y)
  })

我完全没有输出。但是,如果我使用 unmarshal 而不是 flatMap,我会得到输出:

 val future1:Future[String] = Http()
    .singleRequest(
      HttpRequest(method = HttpMethods.GET,
                  uri = "http://localhost:8187/hello")).flatMap(resp => Unmarshal(resp).to[String])

为什么 mapTo 在这里失败,为什么我需要 flatMap 和 Unmarshal?

编辑:

我了解 Unmarhsal 的必要性,我正在尝试了解 map 和 flatMap 之间的区别

例如,下面的代码给出了我预期的结果:

val future1:Future[String] = Http().singleRequest(
          HttpRequest(method = HttpMethods.GET,
                      uri = http://localhost:8187/hello")).flatMap(testFlatFunc)

  def testFlatFunc(x:HttpResponse):Future[String]={
    return Unmarshal(x).to[String]
  }

但是,如果我尝试用地图替换它,如下所示,我得到的输出为 FulfilledFuture(You just accessed hello)

 val future1:Future[String] = Http()
    .singleRequest(
      HttpRequest(method = HttpMethods.GET,
                  uri = "http://localhost:8187/hello")).map(testFunc)

  def testFunc(x:HttpResponse): String={
    return Unmarshal(x).to[String].toString
  }

请参阅下面 mapTo 的文档

  /** Creates a new `Future[S]` which is completed with this `Future`'s result if
   *  that conforms to `S`'s erased type or a `ClassCastException` otherwise.
   */

mapTo[S]本质上对应一个cast。 Http().singleRequest 产生一个 Future[HttpResponse],而 HttpResponse 不能直接转换为 String

需要编组以指定要转换为 String 的有意义的逻辑。因此,在您的情况下,您在提供此功能的范围内有一个隐式的 Unmarshaller 。这很可能是 Akka-HTTP 预定义集中的默认值 stringUnmarshaller。有关这方面的更多信息,请参阅 docs.