3

これは Play 1.x で可能だったと思いますが、Play 2.x でそれを行う方法が見つかりません。

Play が非同期で s を使用していることは知っていますIteratee。ただし、一般に、s のサポートははるかに優れていInputStreamます。

(この場合、Jackson のようなストリーミング JSON パーサーを使用して、要求本文を処理します。)

InputStreamチャンクされたリクエストボディからを取得するにはどうすればよいですか?

4

2 に答える 2

2

次のコードでこれを機能させることができました。

// 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)
  }
}
于 2014-10-02T12:57:22.123 に答える