【问题标题】:How to get InputStream from request in Play如何从 Play 中的请求中获取 InputStream
【发布时间】:2014-07-26 14:45:02
【问题描述】:

我认为这在 Play 1.x 中曾经是可能的,但我在 Play 2.x 中找不到如何做到这一点

我知道 Play 是异步的并且使用 Iteratees。但是,通常对InputStreams 有更好的支持。

(在这种情况下,我将使用像 Jackson 这样的流式 JSON 解析器来处理请求正文。)

如何从分块的请求正文中获取InputStream

【问题讨论】:

    标签: scala playframework-2.0 chunked


    【解决方案1】:

    我能够使用以下代码来实现这一点:

    // I think all of the parens and braces line up -- copied/pasted from code
    val pos = new PipedOutputStream()
    val pis = new PipedInputStream(pos)
    val result = Promise[Either[Errors, String]]()
    
    def outputStreamBodyParser = {
      BodyParser("outputStream") {
        requestHeader =>
          val length = requestHeader.headers(HeaderNames.CONTENT_LENGTH).toLong
    
          Future {
            result.completeWith(saveFile(pis, length)) // save returns Future[Either[Errors, String]]
          }
    
          Iteratee.fold[Array[Byte], OutputStream](pos) {
            (os, data) =>
              os.write(data)
              os
          }.map {
            os =>
              os.close()
              Right(os)
          }
      }
    }
    
    Action.async(parse.when(
      requestHeaders => {
        val maybeContentLength = requestHeaders.headers.get(HeaderNames.CONTENT_LENGTH)
        maybeContentLength.isDefined && allCatch.opt(maybeContentLength.get.toLong).isDefined
      },
      outputStreamBodyParser,
      requestHeaders => Future.successful(BadRequest("Missing content-length header")))) {
        request =>
        result.future.map {
          case Right(fileRef) => Ok(fileRef)
          case Left(errors) => BadRequest(errors)
      }
    }
    

    【讨论】:

      【解决方案2】:

      Play 2 旨在完全异步,因此这不太可能或不可取。 InputStream 的问题是没有推回,InputStream 的读者无法在不阻塞read 的情况下与输入进行通信,它需要更多数据。从技术上讲,可以编写一个可以读取数据并将其放入InputStreamIteratee,并在向Enumerator 询问更多数据之前等待InputStream 上对read 的调用,但它会很危险。您必须确保 InputStream 已正确关闭,否则 Enumerator 将永远等待(或直到超时),并且必须从不在ExecutionContextEnumeratorIteratee 相同,否则应用程序可能会死锁。

      【讨论】:

        猜你喜欢
        • 2018-06-25
        • 2010-10-20
        • 2010-10-13
        • 1970-01-01
        • 2018-06-28
        • 1970-01-01
        • 2015-05-23
        • 2013-05-30
        • 1970-01-01
        相关资源
        最近更新 更多