如何将 csv 文件作为 akka http 响应发送?

How to send csv file as akka http response?

我需要从数据库中获取数据并创建数据的 CSV 文件,return 它和文件应该被下载。并在发送响应后从服务器中删除。我用这个 Simple CSV streaming example

代码片段:

def getAllRetailersCsvData: Route =
post {
  entity(As[String]) { body =>

  //removed database calls and added data from db 
  val retailersInformation = RetailersInformation(
                              List(
                              RetailerInformation(Target,277,8360.56,267.12),
                              RetailerInformation(Amazon,85,1370.0,540.11),
                              RetailerInformation(Walmart,77,1431.32,344.38),
                              RetailerInformation(Best buy,63,1213.22,160.84),
                              RetailerInformation(Others,22,391.77,108.1),
                              RetailerInformation(Others,17,317.86,157.93),
                              RetailerInformation(Ebay,4,46.97,14.55),
                              RetailerInformation(Big lots,3,24.0,12.33),
                              RetailerInformation(Smith's,2,44.98,218.43),
                              RetailerInformation(Kroger,2,39.98,29.09)),23)


  implicit val retailerAsCsv = Marshaller.strict[RetailersInformation, ByteString] { t =>
  Marshalling.WithFixedContentType(ContentTypes.`text/csv(UTF-8)`, () => {
  ByteString(t.retailersInformation.map(r => csvData(r)).mkString("\n"))
})
}

  implicit val csvStreaming: CsvEntityStreamingSupport = EntityStreamingSupport.csv()

  val eventualRetailersInfo = Future(retailersInformation)
  onComplete(eventualRetailersInfo) {

  case Success(info: RetailersInformation) =>
  complete(Source.single(info))
  case Failure(exception) =>
  logger.error(s"Got an exception when getting all retailers info by $campaignId , exception $exception")
  complete(HttpResponse(InternalServerError, entity = generate(ErrorResponse(ErrorMessage))))
}
}
}

问题是当我从 post 人那里找到路线时,我得到了正确的内容,但没有得到 csv 文件。

输出:

Retailer Name,Receipts Submitted,Brand Total,Basket Size
"Target","277","267.12","8360.56"
"Amazon","85","540.11","1370.0"
"Walmart","77","344.38","1431.32"
"Best buy","63","160.84","1213.22"
"Others","22","108.1","391.77"
"Others","17","157.93","317.86"
"Ebay","4","14.55","46.97"
"Big lots","3","12.33","24.0"
"Smith's","2","218.43","44.98"
"Kroger","2","29.09","39.98"

我有一些与流式 csv 示例不同的东西。我有一个 post 请求。不确定在哪里设置只接受 csv 文本的 header。如果我正在接受,请指导我,因为我是 Akka 流概念的初学者。任何帮助将不胜感激。

谢谢

我猜你从 Akka http 获得了原始数据,你可以将其转换为适当的响应 使用 curl --output example.csv **application url**

为了解决这个问题,我首先创建一个文件作为 HTTP 响应传递。

def writeToFile(content: String, campaignId: String): File = {
    val tempFolder = System.getProperty(TempDir)
    val file = new File(s"$tempFolder/retailers_$campaignId.csv")
    val bw = new BufferedWriter(new FileWriter(file))
    bw.write(content)
    bw.close()
    file
  }

def retailersInfoForCsvResponseHandler(response: Either[Throwable, Option[String]], campaignId: String): HttpResponse =
    response.fold({ err =>
      logger.error(s"An exception has occurred while getting retailersInfo for csv from snap3 service ${err.getMessage}")
      HttpResponse(StatusCodes.InternalServerError, entity = err.getMessage)
    }, response => {
      val file = writeToFile(response.fold("")(identity), campaignId)
      val source = FileIO.fromPath(file.toPath)
        .watchTermination() { case (_, result) =>
          result.onComplete(_ => file.delete())
        }

      HttpResponse(status = StatusCodes.OK, entity = HttpEntity(ContentTypes.`text/csv(UTF-8)`, source))
    })

它对我有用。文件作为响应发送,文件在响应发送后被删除。