Scala 使用分块传输文件下载进行内容处置
我有一个在Jetty上运行的Spray应用程序,它向客户端发送PDF。分块发送文件很方便,因为它可能会变得非常大 问题在于,尽管设置了Scala 使用分块传输文件下载进行内容处置,scala,download,akka,spray,content-disposition,Scala,Download,Akka,Spray,Content Disposition,我有一个在Jetty上运行的Spray应用程序,它向客户端发送PDF。分块发送文件很方便,因为它可能会变得非常大 问题在于,尽管设置了内容配置和媒体类型字段,但文件在浏览器中呈现,而不是下载 责任参与者的recieve()方法: val chunkIterator: Iterator[HttpData] = httpData.iterator def receive = { case FirstChunk if chunkIterator.hasNext =>
内容配置
和媒体类型
字段,但文件在浏览器中呈现,而不是下载
责任参与者的recieve()
方法:
val chunkIterator: Iterator[HttpData] = httpData.iterator
def receive = {
case FirstChunk if chunkIterator.hasNext =>
val starterResponse = HttpResponse(headers = List(HttpHeaders
.`Content-Disposition`.apply("attachment", Map("filename" -> FILENAME)))
, entity = HttpEntity(MediaTypes.`application/pdf`, chunkIterator.next)
)
ctx.responder ! ChunkedResponseStart(starterResponse).withAck(ResponseAck)
case FirstChunk =>
ctx.responder ! ChunkedResponseStart(HttpResponse(entity = Empty))
context.stop(self)
case ResponseAck if chunkIterator.hasNext =>
val nextChunk = MessageChunk(chunkIterator.next)
ctx.responder ! nextChunk.withAck(ResponseAck)
case ResponseAck =>
ctx.responder ! ChunkedMessageEnd
context.stop(self)
case error => log.warning("connection closed due to {}", error)
}
从浏览器中看到的标题
Content-Disposition → attachment; filename=file.pdf
Content-Type → application/pdf
Date → Fri, 04 May 2015 09:13:57 GMT
Server → Jetty(9.2.10.v20150310)
Transfer-Encoding → chunked
关于如何强制下载该文件的任何线索
使用MetaMarshaller.streamMarshaller[T]
implicit val pdfStreamMarshaller = MetaMarshallers.streamMarshaller[Array[Byte]]
val route = {
path("api" / "pdfservice") {
post {
respondWithHeader(`Content-Disposition`("attachment", Map(("filename", "some.pdf")))) {
respondWithMediaType(MediaTypes.`application/pdf`) {
entity(as[Params]) {
params => {
ctx => {
onComplete(
getPdfStream(params)
){
case Success(value) => ctx.complete(value)
case Failure(ex) => ctx.complete(s"Oops, error encountered ${ex.getMessage}")
}
}
}
}
}
}
}
private def getStream(params: Params) :Future[Array[Byte]]
编辑:修复了方法2[将数据转换为
流[T]
]时的编译问题,但仍然存在相同的问题,文件下载选项没有显示,而是在浏览器中呈现为文本。在各种操作系统上使用各种浏览器进行测试 是否有任何理由不返回流[T]
使用spray?我几乎一字不差地将您的starterResponse
复制到最新spray源代码的on spray can和on jetty示例中,在那里它绝对有效。在过去,一些浏览器(即…)在解释内容配置时遇到一些问题,因此可能是浏览器问题?@jrudolph这可能是由于缺少明确的封送器造成的吗?我有一个简单的函数,可以将生成的PDF流转换为HttpData
private def arrayToHttpData(data:bytearrayoutpstream)={Iterable(data.toByteArray.map(HttpData.apply)}
@jrudolph:我在Linux上使用最新版本的Chrome/Firefox进行测试(晚了一年),谢谢@jrudolph。这确实是一个浏览器问题。