喷涂内容 - 处理与分块传输文件下载

时间:2015-05-05 09:15:55

标签: scala download akka spray content-disposition

我在Jetty上运行了一个Spray应用程序,它将PDF发送给客户端。以块的形式发送文件很方便,因为它可能会变得非常大。

问题是尽管设置了Content-DispositionMedia-Type字段,但文件在浏览器中呈现而不是下载。

负责人的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

有关如何强制下载文件的任何线索?

使用MetaMarshallers.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 [将数据转换为Stream[T]]修复了编译问题,但它仍然存在相同的问题,文件下载选项未显示,而是在浏览器中呈现为文本。在各种操作系统上使用各种浏览器进行测试。

0 个答案:

没有答案