首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将HttpEntity.Chunked转换为Array[String]

将HttpEntity.Chunked转换为Array[String]
EN

Stack Overflow用户
提问于 2016-03-14 20:17:45
回答 1查看 2.2K关注 0票数 1

我有以下问题。我正在查询服务器中的一些数据,并将其作为HttpEntity.Chunked返回。响应字符串看起来如下所示,最多10.000.000行如下所示:

代码语言:javascript
复制
[{"name":"param1","value":122343,"time":45435345},
{"name":"param2","value":243,"time":4325435},
......]

现在,我希望将传入的数据输入到和ArrayString中,其中每个字符串都是响应的一行,因为稍后应该将其导入。目前我正在这样做:

代码语言:javascript
复制
//For the http request
trait StartHttpRequest {
  implicit val system: ActorSystem
  implicit val materializer: ActorMaterializer

  def httpRequest(data: String, path: String, targetPort: Int, host: String): Future[HttpResponse] = {
    val connectionFlow: Flow[HttpRequest, HttpResponse, Future[OutgoingConnection]] = {
      Http().outgoingConnection(host, port = targetPort)
    }
    val responseFuture: Future[HttpResponse] =
      Source.single(RequestBuilding.Post(uri = path, entity = HttpEntity(ContentTypes.`application/json`, data)))
        .via(connectionFlow)
        .runWith(Sink.head)
    responseFuture
  }
}

//result of the request
val responseFuture: Future[HttpResponse] = httpRequest(.....)

//convert to string
responseFuture.flatMap { response =>
        response.status match {
          case StatusCodes.OK =>
            Unmarshal(response.entity).to[String]
    }
}

//and then something like this, but with even more stupid stuff
responseFuture.onSuccess { str:String =>
    masterActor! str.split("""\},\{""")
}

我的问题是,怎样才能更好地将结果输入数组?如何才能直接解开响应实体?例如,因为.to[ArrayString]不起作用。因为有那么多行,我能用一条小溪来做吗,这样才能更有效?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-15 18:41:23

回答你的问题不符合规程:

如何才能直接解锁响应实体?

有一个与解编组案例类数组相关的existing question & answer

,有什么更好的方法可以将结果转化为数组?

我会利用这一团块的自然,利用溪流。这允许您同时执行字符串处理和json解析。

首先,需要一个容器类和解析器:

代码语言:javascript
复制
case class Data(name : String, value : Int, time : Long)

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit val dataFormat = jsonFormat3(Data)
}

然后,您必须执行一些操作才能使json对象看起来正确:

代码语言:javascript
复制
//Drops the '[' and the ']' characters
val dropArrayMarkers = 
  Flow[ByteString].map(_.filterNot(b => b == '['.toByte || b == ']'.toByte))

val preppendBrace = 
  Flow[String].map(s => if(!s.startsWith("{")) "{" + s else s)

val appendBrace = 
  Flow[String].map(s => if(!s.endsWith("}")) s + "}" else s)

val parseJson = 
  Flow[String].map(_.parseJson.convertTo[Data])

最后,结合这些流将ByteString源转换为数据对象的源:

代码语言:javascript
复制
def strSourceToDataSource(source : Source[ByteString,_]) : Source[Data, _] = 
  source.via(dropArrayMarkers)
        .via(Framing.delimiter(ByteString("},{"), 256, true))
        .map(_.utf8String)
        .via(prependBrace)
        .via(appendBrace)
        .via(parseJson)

然后,可以将此源排入数据对象的Seq中:

代码语言:javascript
复制
val dataSeq : Future[Seq[Data]] = 
  responseFuture flatMap { response =>
    response.status match {
      case StatusCodes.OK =>
        strSourceToDataSource(response.entity.dataBytes).runWith(Sink.seq)
    }
  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35997244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档