scala - 如何将 csv 文件作为 akka http 响应发送?
问题描述
我需要从数据库中获取数据并创建 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 流概念的初学者。任何帮助将不胜感激。
谢谢
解决方案
要解决此问题,首先我创建一个文件以作为 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))
})
它对我有用。并且作为响应发送的文件和文件在发送响应后被删除。
推荐阅读
- android - Android - 位置权限 - 来自警报框的响应
- javascript - 在 react-bootstrap 选择输入中显示选择的 i18next 语言
- java - 将字符串对象分成标记?
- java - 如何解决警报通知问题
- reactjs - 在 Reactjs 中使用多个文件输入时如何限制选择的最大文件数?
- javascript - 交叉点观察者无法处理通过 JS 添加的元素
- c# - 排队 ConcurrentQueue 时如何修复命令串联
在unity3d c#中? - java - (JavaFX) 动态添加列。但没有添加数据
- python - 在 for 循环中绘制所有变量
- c# - BadImageFormatException - 将 C# 控制台项目与 C# Windows 窗体项目合并