【问题标题】:Decode gzipped JSON in Akka HTTP在 Akka HTTP 中解码 gzip 后的 JSON
【发布时间】:2016-12-24 13:40:27
【问题描述】:

我有一个可以调用 /test 的端点,它在内部从第 3 方 API 获取数据,然后想要在返回响应之前进行一些转换。我挂断的地方是这个第 3 方 API 正在返回 gzip 压缩的 JSON,但我无法解码它(还)。我找到了decodeRequest directive,但似乎我必须在我的路由中使用它,而且我在这里更深一层。我有一个内部方法,一旦我收到一个名为do3rdPartyAPIRequest 的端点/testGET,我就会调用它,在那里我建立一个HttpRequest 并传递给Http().singleRequest(),所以作为回报,我有一个Future[HttpResponse]这是我想去的地方,但我被困在这里。

对于我以类似方式构建和使用的一些本地 API,我没有对响应进行编码,因此通常使用 Future[HttpResponse] 检查响应状态并通过 Unmarshal 转换为 JSON,但这需要额外的据我所知,在转换为 JSON 之前先一步。我意识到这个问题与this one 非常相似,但是这是特定于喷雾的,我无法将这个答案翻译成当前的 akka http

【问题讨论】:

    标签: json scala akka-http


    【解决方案1】:

    终于想通了——这可能不是从响应中获取字节串的绝对最佳方法,但它确实有效。事实证明你可以使用Gzip class

    你有两个选择

    1. Gzip.decode
    2. Gzip.decoderFlow

    以下是我的示例,以防对您有所帮助:

    def getMyDomainObject(resp: HttpResponse):Future[MyDomain] = {
     for {
       byteString <- resp.entity.dataBytes.runFold(ByteString(""))(_ ++ _)
       decompressedBytes <- Gzip.decode(byteString)
       result <- Unmarshal(decompressedBytes).to[MyDomain]
      } yield result
    }
    
    
    def getMyDomainObjectVersion2(resp:HttpResponse):Future[MyDomain] = {
       resp.entity.dataBytes
       .via(Gzip.decoderFlow)
       .runWith(Sink.head)
       .flatMap(Unmarshal(_).to[MyDomain])
    }
    

    【讨论】:

      【解决方案2】:

      您可能希望压缩内容默认由 akka-http 管理,但它只提供 PredefinedFromEntityUnmarshallers 并且在实体内部没有关于 Content-encoding 标头的信息。

      要解决这个问题,您必须实现自己的 Unmarshaller 并将其纳入范围

      例子:

      implicit val gzipMessageUnmarshaller = Unmarshaller(ec => {
            (msg: HttpMessage) => {
              val `content-encoding` = msg.getHeader("Content-Encoding")
              if (`content-encoding`.isPresent && `content-encoding`.get().value() == "gzip") {
                val decompressedResponse = msg.entity.transformDataBytes(Gzip.decoderFlow)
                Unmarshal(decompressedResponse).to[String]
              } else {
                Unmarshal(msg).to[String]
              }
            }
          }) 
      

      【讨论】:

        猜你喜欢
        • 2017-10-03
        • 2023-03-19
        • 1970-01-01
        • 2019-07-01
        • 2019-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-11
        相关资源
        最近更新 更多