Springファイルのアップロードと接続のリセットの問題
ファイルアップロード制限、ファイルごとに5 MB、要求ごとに10 MBを構成するSpringサーブレットの初期化子。
MyWebInitializer.java
public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { private int maxUploadSizeInMb = 5 * 1024 * 1024; // 5 MB //... @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { // upload temp file will put here File uploadDirectory = new File(System.getProperty("java.io.tmpdir")); // register a MultipartConfigElement MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), maxUploadSizeInMb, maxUploadSizeInMb * 2, maxUploadSizeInMb / 2); registration.setMultipartConfig(multipartConfigElement); } }
アップロード制限よりも大きいファイルサイズをアップロードしようとすると、20 MBと言います。次の奇妙な「接続リセット」エラーが表示されます。
グローバル@ControllerAdvice
でさえ、上記の例外をキャッチできません。
テスト済み
-
Spring 4.3.5.RELEASE
-
Tomcat 8
1. 溶液
数日間の調査と調査の結果、問題はSpringに関連していないことがわかりました(Jettyにデプロイしても問題ありません)。これは、TomcatのデフォルトコネクタmaxSwallowSize
です。
アップロードの中止のためにTomcatによって飲み込まれるリクエスト本文の最大バイト数(転送エンコーディングのオーバーヘッドを除く)。 アップロードの中止とは、Tomcatがリクエスト本文が無視されることを認識しているが、クライアントがまだ送信している場合です。 Tomcatがボディを飲み込まない場合、クライアントは応答を見ることはほとんどありません。 指定しない場合、デフォルトの2097152(2メガバイト)が使用されます。 ゼロ未満の値は、制限を適用しないことを示します。
サイズ制限を超えたファイルサイズをアップロードしようとすると、Tomcatはデフォルトの2 MBで切り取り、接続をリセットします。 すばやく解決するには、maxSwallowSize
に-1(無制限)を入力します
Tomcat/conf/server.xml
この-1は開発には適していますが、実稼働には適していません。ユーザーが100 MBのファイルをアップロードしようとすると、Tomcatは余分な帯域幅を処理するためにリソースを浪費します。
2. Idea
2. 1ファイルのアップロードに適切な制限を設定してみてください。たとえば、この例では11mb
(11 x 1024 x 1024 =バイト)です。
Tomcat/conf/server.xml
2.2 And implement a Javascript to check the file size before the upload.
What about Jetty?
Jetty 9でテストしたところ、maxSwallowSize
の設定を見つけることができず、ファイルサイズがアップロード制限を超えても接続がリセットされません。