PlayFramework 2.4.6を使用していて、マルチパートファイル(サイズ18M)をアップロードしようとすると、サーバーが次のエラーを返します。
For request 'POST /api/myEndpoint' [Request Entity Too Large]
私は周りを見回して、成功せずに次のことを試しました:
そして、それらのどれも問題を解決しません。
ここにもスタックトレースがあります:
14:57:33.128 [New I/O worker #2] [error] - p.c.server.netty.RequestBodyHandler - Exception caught in RequestBodyHandler Java.nio.channels.ClosedChannelException: null at org.jboss.netty.channel.socket.nio.AbstractNioWorker.setInterestOps(AbstractNioWorker.Java:506) [netty-3.10.4.Final.jar:na] at org.jboss.netty.channel.socket.nio.AbstractNioWorker$1.run(AbstractNioWorker.Java:455) [netty-3.10.4.Final.jar:na] at org.jboss.netty.channel.socket.ChannelRunnableWrapper.run(ChannelRunnableWrapper.Java:40) [netty-3.10.4.Final.jar:na] at org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.Java:391) [netty-3.10.4.Final.jar:na] at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.Java:315) [netty-3.10.4.Final.jar:na] at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.Java:89) [netty-3.10.4.Final.jar:na] at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.Java:178) [netty-3.10.4.Final.jar:na] at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.Java:108) [netty-3.10.4.Final.jar:na] at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.Java:42) [netty-3.10.4.Final.jar:na] at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142) [na:1.8.0_65] at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617) [na:1.8.0_65] at Java.lang.Thread.run(Thread.Java:745) [na:1.8.0_65]
これで問題を解決しました:
play.http.parser.maxDiskBuffer = 100MB
parsers.anyContent.maxLength = 100MB
大きなフォームとplay.http.parser.maxMemoryBuffer=4MB
解決しました。
Playが使用するメモリとディスクバッファーについては、このドキュメントを参照してください。 https://www.playframework.com/documentation/2.4.x/ScalaBodyParsers#Max-content-length
テキストベースの本文パーサー(text、json、xml、formUrlEncodedなど)では、すべてのコンテンツをメモリに読み込む必要があるため、最大コンテンツ長を使用します。デフォルトでは、ユーザーが解析するコンテンツの最大長は100KBです。これは、application.confで
play.http.parser.maxMemoryBuffer
プロパティを指定することでオーバーライドできます。
play.http.parser.maxMemoryBuffer=128K
Rawパーサーやmultipart/form-dataなど、ディスク上のコンテンツをバッファーするパーサーの場合、最大コンテンツ長は
play.http.parser.maxDiskBuffer
プロパティを使用して指定され、デフォルトは10MB。 multipart/form-dataパーサーは、データフィールドの集約にテキストの最大長プロパティも適用します。
したがって、マルチパートファイルをアップロードしようとしているので、play.http.parser.maxDiskBuffer
を18 MBより大きくする必要があります。
したがって、これをapplication.confに追加すると修正できます。
play.http.parser.maxDiskBuffer=100MB
Play Framework 2.6.xの問題に直面している人は、 https://www.playframework.com/documentation/2.6.x/ScalaBodyParsers のドキュメントを参照してください
最大コンテンツ長テキストベースのボディパーサー(text、json、xml、formUrlEncodedなど)では、すべてのコンテンツをメモリに読み込む必要があるため、最大コンテンツ長を使用します。デフォルトでは、ユーザーが解析するコンテンツの最大長は100KBです。 application.confでplay.http.parser.maxMemoryBufferプロパティを指定することで上書きできます:
application.confに以下を追加します。
play.http.parser.maxMemoryBuffer = 5MB
私の場合、AnyContent
パーサーを使用しています。コードを機能させるために、controller
の定義を次のように変更しました
def newQuestion = silhouette.SecuredAction.async(parse.maxLength(1024 * 1024, parse.anyContent)(ActorMaterializer()(ActorSystem("MyApplication")))){
implicit request => {
println("got request with body:" + request.body)
val anyBodyErrors: Either[MaxSizeExceeded, AnyContent] = request.body
anyBodyErrors match {
case Left(size) => {
Future {
EntityTooLarge(Json.toJson(JsonResultError(messagesApi("error.entityTooLarge")(langs.availables(0)))))
}
}
case Right(body) => {
//val body:AnyContent = request.body
val jsonBodyOption = body.asJson
...
}
}