これは Play 1.x で可能だったと思いますが、Play 2.x でそれを行う方法が見つかりません。
Play が非同期で s を使用していることは知っていますIteratee
。ただし、一般に、s のサポートははるかに優れていInputStream
ます。
(この場合、Jackson のようなストリーミング JSON パーサーを使用して、要求本文を処理します。)
InputStream
チャンクされたリクエストボディからを取得するにはどうすればよいですか?
これは Play 1.x で可能だったと思いますが、Play 2.x でそれを行う方法が見つかりません。
Play が非同期で s を使用していることは知っていますIteratee
。ただし、一般に、s のサポートははるかに優れていInputStream
ます。
(この場合、Jackson のようなストリーミング JSON パーサーを使用して、要求本文を処理します。)
InputStream
チャンクされたリクエストボディからを取得するにはどうすればよいですか?
次のコードでこれを機能させることができました。
// 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)
}
}