在Spray中将CSV文件流式传输到浏览器

时间:2014-07-28 15:25:39

标签: scala csv spray

在我的应用程序的一部分中,我必须将CSV文件发送回浏览器。我有一个回复Stream [String]的actor,Stream的每个元素都是文件中应该发送给用户的一行。

这就是我现在拥有的。请注意,我目前正在返回MediaType text/plain进行调试,最终版本为text/csv

trait TripService extends HttpService
                          with Matchers
                          with CSVTripDefinitions {
  implicit def actorRefFactory: ActorRefFactory

  implicit val executionContext = actorRefFactory.dispatcher

  lazy val csvActor = Ridespark.system.actorSelection(s"/user/listeners/csv").resolveOne()(1000)

  implicit val stringStreamMarshaller = Marshaller.of[Stream[String]](MediaTypes.`text/plain`) { (v, ct, ctx) =>
    ctx.marshalTo(HttpEntity(ct, v.mkString("\n")))
  }

  val route = {
    get {
          path("trips" / Segment / DateSegment) { (network, date) =>
            respondWithMediaType(MediaTypes.`text/plain`) {
                                                            complete(askTripActor(date, network))
                                                          }
                                                }
        }
  }

  def askTripActor(date: LocalDate, network: String)
                  (implicit timeout: Timeout = Timeout(1000, TimeUnit.MILLISECONDS)): Future[Stream[String]] = {
    csvActor flatMap { actor => (actor ? GetTripsForDate(date, Some(network))).mapTo[Stream[String]] }
  }
}

class TripApi(info: AuthInfo)(implicit val actorRefFactory: ActorRefFactory) extends TripService

我的问题是它会将整个CSV加载到内存中(由于mkString中的stringStreamMarshaller)。有没有办法不这样做,在生成CSV时流式传输CSV线?

1 个答案:

答案 0 :(得分:2)

您不需要stringStreamMarshaller。使用内置的流marshaller应该已经做了你想要的,而不添加额外的换行符。但是,添加换行符不应该比使用streamOfStrings.map(_ + "\n")更困难,或者只是在首先在csv-actor中渲染行时添加换行符。