SpringBootのTomcatのPostサイズ制限にハマった人へ
背景
Tomcatを使ったことがある人なら誰しもPostデータサイズのデフォルト制限(2MB)に引っかかって、Tomcatの設定を見直したことがあると思う。
私も以前に同じ経験をしたことがあり、そのときにTomcatのドキュメントを見直して「わかりにくいなー」と思った記憶があるが、そのときは特に記事にするほどでもないと思い、自分の記憶に留めておくだけで終わらせた。
けどつい最近、SpringBootでも同じ制限にひっかかったので、今後のためにまとめることにした。
素のTomcatの場合
本題の前に余談。
SpringBootを使わず、素のTomcatだけを使う場合は、$CATALINA_HOME/conf/server.xml
にmaxPostSize
の指定があり、この値を変更することで対処する。maxPostSizeのデフォルトは2MB。
どうでもいいが、公式ドキュメントの記載箇所がわかりにくいと思うのは私だけ? 公式サイトに検索機能がほしいよね。
- Tomcat 公式ドキュメント →「Configuration」→「HTTP1.1」
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxPostSize="2097152"/> <!-- ←ここに設定 -->
SpringBootの組み込みTomcatの場合
今回の本題。
ご存知のとおり、SpringBootは内部にTomcatが組み込まれており、ビルドしたjarファイルだけで簡単にウェブアプリケーションを動作させることができる。
この内部に組み込まれているTomcatにも、デフォルト2MBのPostデータサイズ制限が存在する。
しかし、SpringBootの組み込みTomcatにはserver.xml
が存在しないため、素のTomcatとは違う方法で設定をしなければならない。
結論から言うと、application.properties
に以下の項目を設定することで対処できる。
server.tomcat.max-http-form-post-size=2MB
server.tomcat.max-swallow-size=2MB
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
- SpringBoot公式ドキュメント(最新版)
ハマりポイント1:Content-Typeによって設定すべきプロパティが違う
注意すべきなのは、Post時のContent-Type
がapplication/x-www-form-urlencoded
(HTMLのformからsubmitしたときなど)の場合は、spring.servlet.multipart.max-request-size
の設定が効かない点だ。Qiita上でも「spring.servlet.multipart.max-request-size
設定すれば解決」という記事が多く、以下のStack Overflowの記事を見つけるまで気づけなかった。
If you are using using x-www-form-urlencoded mediatype in your POST requests (as I do), the multipart property of spring-boot does not work. If your spring-boot application is also starting a tomcat, you need to set the following property in your application.properties file:
ハマりポイント2:古いSpringBootではプロパティ名が違う
今現在のSpringBoot最新版(v2.2.5)では上記のプロパティでよいが、古いバージョンだとプロパティ名が違うことがある。(自分もこれでハマって解決するのに時間がかかった)
## server.tomcat.max-http-form-post-size=2MB # v2.2.5の場合はこっち
server.tomcat.max-http-post-size=2MB # v2.1.6などはこっち
- たぶんこれが関連→ https://github.com/spring-projects/spring-boot/issues/18521
- たしかに勘違いしやすいと思う。だからこの記事を書こうと思った。
ちなみに、spring.servlet.multipart.max-file-size
とspring.servlet.multipart.max-request-size
についても、かなり古いSpringBootではプロパティ名が違う(spring.http.multipart.max-file-size
だったりする)ので注意。
まとめ
今回の経験から学んだ教訓
ちゃんとSpringBootのバージョンを確認してからプロパティを調べよう
当たり前のことだけどね。