在我的应用程序的一部分中,我必须将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线?
答案 0 :(得分:2)
您不需要stringStreamMarshaller
。使用内置的流marshaller应该已经做了你想要的,而不添加额外的换行符。但是,添加换行符不应该比使用streamOfStrings.map(_ + "\n")
更困难,或者只是在首先在csv-actor中渲染行时添加换行符。