Как отправить CSV-файл в виде ответа http akka? - PullRequest
2 голосов
/ 07 июня 2019

У меня есть требование получить данные из базы данных и создать файл данных CSV и вернуть его, и файл должен быть загружен. и удаляются с сервера после отправки ответа. Я использовал этот Простой пример потоковой передачи CSV

Фрагмент кода:

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))))
}
}
}

Проблема в том, что когда я отправляюсь по маршруту от почтальона, я получаю правильный контент, но не файл 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. У меня есть почтовый запрос. Не уверен, где установить заголовок, который принимает только текст CSV. Если я принимаю согласие, пожалуйста, ведите меня, поскольку я новичок в концепции потоков Akka. Любая помощь будет оценена.

Спасибо

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Чтобы решить эту проблему, сначала я создаю файл для передачи в качестве ответа 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))
    })

Это сработало для меня. И файл, отправленный как ответ, и файл удаляются после того, как ответ был отправлен.

0 голосов
/ 10 июня 2019

Полагаю, из Akka http вы получаете необработанные данные. Вы можете преобразовать их в соответствующий ответ, используя curl --output example.csv **application url**

...