Scala 当使用自定义对象而不是Httpresponse时,如何获取响应代码

Scala 当使用自定义对象而不是Httpresponse时,如何获取响应代码,scala,spray,spray-json,Scala,Spray,Spray Json,当我使用 val pipeline: HttpRequest => Future[HttpResponse] = addHeader(.......) ~> sendReceive ~> unmarshal[HttpResponse] 然后,我可以使用它作为HttpResponse的对象来获取状态代码 val futureResponse = pipeline(Post(url, body)) futureResponse.map(_.status

当我使用

val pipeline: HttpRequest => Future[HttpResponse] = addHeader(.......) ~> sendReceive ~>       unmarshal[HttpResponse]        
然后,我可以使用它作为HttpResponse的对象来获取状态代码

val futureResponse = pipeline(Post(url, body)) futureResponse.map(_.status)
但是,当我将自定义解组器用作:

val pipeline: HttpRequest => Future[MyResponse] = addHeader(.......) ~> sendReceive ~>      unmarshal[MyResponse]
使用


无法编译,因为它找不到状态。如何在此处获取状态代码?我需要使用自定义解组器才能反序列化我的json结果。

如果在管道中对联合国封送处理程序进行硬编码,则无法获取状态代码。您仍然会得到失败代码,因为它们将是导致未来失败的异常的一部分

如果您确实希望保留该信息并在管道中使用un封送拆收器,则需要编写自己的un封送拆收器,以向您提供此类响应:

case class Wrapper[T](response: T, status: StatusCode)

val pipeline: HttpRequest => Future[Wrapper[MyResponse]] = addHeader(.......) ~> sendReceive ~> myUnmarshall[MyResponse]

如果你不知道喷雾器的内部结构,这可能会变得相当棘手。另一种选择是不要硬编码管道中的
解组
位,并手动反序列化JSON。

最后,我根据您的建议找到了答案

private def unmarshal[T: Unmarshaller](response: HttpResponse): T = {
response.entity.as[T] match {
  case Right(value) => value
  case Left(error)  ⇒ throw new PipelineException(error.toString)
}
}

我将管道方法更改为

val pipeline: HttpRequest => HttpResponse = addHeader(.......) ~> sendReceive
val searchResponse = pipeline(Post(urlwithpath, queryString)).map {
  response => response.status match {
    case StatusCodes.OK =>
      Some(unmarshal[MyResponse](response))
    case StatusCodes.NotFound => print(StatusCodes.NotFound)
   }
}

现在我已经解决了这个问题,我将正确地学习API

好的,很酷。谢谢你的指点,我想发出一个获取主体的请求,然后再发出一个获取代码的请求是不可以的。有趣的是,我不知道我在解组器中硬编码了值。我只是在遵循我在互联网上找到的例子。我的意思是,你正在硬编码解包器,作为你的管道的一部分。你可以看看它是如何实现的,如果你想有一个不同的行为,你可以实现你的。仍然不是100%清楚的建议解决方案。不幸的是,互联网上没有太多的例子。我在网上看到的一个解决方案是,有一种方法可以捕获httpresonse并在解包前放入管道中,例如'code'def mapStatus:HttpResponse=>HttpResponse={case r@HttpResponse(status,entity,u,u)=>r.withEntity(entity.map((ct,buf)=>ContentType.
application/json
->buf))案例x=>x}val管道:HttpRequest=>Future[Wrapper[MyResponse]]=addHeader(..)~>sendReceive~>mapStatus~>myUnmarshall[MyResponse]上述示例将实体提取到HttpResponse对象中,然后放入管道,但我无法对status执行相同的操作
val pipeline: HttpRequest => HttpResponse = addHeader(.......) ~> sendReceive
val searchResponse = pipeline(Post(urlwithpath, queryString)).map {
  response => response.status match {
    case StatusCodes.OK =>
      Some(unmarshal[MyResponse](response))
    case StatusCodes.NotFound => print(StatusCodes.NotFound)
   }
}