Ошибка PlayFramework 2.4.6 413 Запросить сущность слишком большого

Я использую PlayFramework 2.4.6, пытаясь загрузить многостраничный файл (размер 18M), и сервер возвращает следующую ошибку:

For request 'POST /api/myEndpoint' [Request Entity Too Large]

Я огляделся и попробовал следующее:

  • play.http.parser.maxMemoryBuffer = 2000000K
  • parsers.MultipartFormData.maxLength = 1024000K
  • play.http.parser.maxDiskBuffer = 2000000K
  • Action.async(parse.anyContent(Некоторые из них (1024 * 200L)))

И ни одна из них не решает проблему.

Вот также Stacktrace:

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]

Ответ 1

Решил проблему с этим:

play.http.parser.maxDiskBuffer = 100MB

parsers.anyContent.maxLength = 100MB

Ответ 2

У меня была та же проблема, что и отправка большой формы, и play.http.parser.maxMemoryBuffer=4MB решил ее.

Ответ 3

См. Эту документацию о памяти и дисковых буферах, которые использует Play: https://www.playframework.com/documentation/2.4.x/ScalaBodyParsers#Max-content-length

Текстовые парсеры тела (такие как text, json, xml или formUrlEncoded) используют максимальную длину контента, потому что они должны загружать весь контент в память. По умолчанию максимальная длина содержимого, которое они будут анализировать, составляет 100 КБ. Его можно переопределить, указав свойство play.http.parser.maxMemoryBuffer в application.conf:

play.http.parser.maxMemoryBuffer=128K

Для анализаторов, которые буферизуют содержимое на диске, таких как необработанный анализатор или multipart/form-data, максимальная длина содержимого указывается с play.http.parser.maxDiskBuffer свойства play.http.parser.maxDiskBuffer, по умолчанию оно play.http.parser.maxDiskBuffer 10 МБ. Анализатор multipart/form-data также применяет свойство максимальной длины текста для совокупности полей данных.

Итак, поскольку вы пытаетесь загрузить многокомпонентный файл, вам нужно увеличить play.http.parser.maxDiskBuffer до 18 МБ.

Итак, добавление этого в ваш application.conf должно исправить это:

play.http.parser.maxDiskBuffer=100MB

Ответ 4

Для тех, кто сталкивается с проблемой в Play Framework 2.6.x, см. документацию на https://www.playframework.com/documentation/2.6.x/ScalaBodyParsers

Максимальная длина контента Текстовые синтаксические анализаторы тела (такие как текст, json, xml или formUrlEncoded) используют максимальную длину содержимого, так как они должны загружать все содержимое в память. По умолчанию максимальная длина контента, которая они будут разбираться в 100 КБ. Его можно переопределить, указав Свойство play.http.parser.maxMemoryBuffer в application.conf:

добавить в application.conf следующее:

play.http.parser.maxMemoryBuffer = 5MB

Ответ 5

В моем случае я использую парсер 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
...
}
}