1. 概要

Springフレームワークでは、アプリケーションが構成で指定された特定のしきい値を超えるサイズのファイルをアップロードしようとすると、MaxUploadSizeExceededExceptionがスローされます。

このチュートリアルでは、最大アップロードサイズを指定する方法を見ていきます。 次に、簡単なファイルアップロードコントローラーを示し、この例外を処理するためのさまざまな方法について説明します。

2. 最大アップロードサイズの設定

デフォルトでは、アップロードできるファイルのサイズに制限はありません。 最大アップロードサイズを設定するには、タイプMultipartResolverのBeanを宣言する必要があります。

ファイルサイズを5MBに制限する例を見てみましょう。

@Bean
public MultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver
      = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(5242880);
    return multipartResolver;
}

3. ファイルアップロードコントローラー

次に、ファイルのサーバーへのアップロードと保存を処理するコントローラーメソッドを定義しましょう。

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public ModelAndView uploadFile(MultipartFile file) throws IOException {
 
    ModelAndView modelAndView = new ModelAndView("file");
    InputStream in = file.getInputStream();
    File currDir = new File(".");
    String path = currDir.getAbsolutePath();
    FileOutputStream f = new FileOutputStream(
      path.substring(0, path.length()-1)+ file.getOriginalFilename());
    int ch = 0;
    while ((ch = in.read()) != -1) {
        f.write(ch);
    }
    
    f.flush();
    f.close();
    
    modelAndView.getModel().put("message", "File uploaded successfully!");
    return modelAndView;
}

ユーザーが5MBを超えるサイズのファイルをアップロードしようとすると、アプリケーションはタイプMaxUploadSizeExceededExceptionの例外をスローします。

4. MaxUploadSizeExceededExceptionの処理

この例外を処理するために、コントローラーにインターフェース HandlerExceptionResolver を実装させるか、@ControllerAdvice注釈付きクラスを作成することができます。

4.1. HandlerExceptionResolverの実装

HandlerExceptionResolver インターフェースは、 resolveException()と呼ばれるメソッドを宣言します。このメソッドでは、さまざまなタイプの例外を処理できます。

キャッチされた例外がMaxUploadSizeExceededExceptionタイプの場合にメッセージを表示するために、 resolveException()メソッドをオーバーライドしてみましょう。

@Override
public ModelAndView resolveException(
  HttpServletRequest request,
  HttpServletResponse response, 
  Object object,
  Exception exc) {   
     
    ModelAndView modelAndView = new ModelAndView("file");
    if (exc instanceof MaxUploadSizeExceededException) {
        modelAndView.getModel().put("message", "File size exceeds limit!");
    }
    return modelAndView;
}

4.2. コントローラアドバイスインターセプタの作成

コントローラ自体ではなくインターセプタを介して例外を処理することには、いくつかの利点があります。 1つは、同じ例外処理ロジックを複数のコントローラーに適用できることです。

もう1つは、処理する例外のみを対象とするメソッドを作成できることです。これにより、フレームワークは、 instanceof を使用して、スローされた例外のタイプを確認しなくても、例外処理を委任できます。

@ControllerAdvice
public class FileUploadExceptionAdvice {
     
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView handleMaxSizeException(
      MaxUploadSizeExceededException exc, 
      HttpServletRequest request,
      HttpServletResponse response) {
 
        ModelAndView modelAndView = new ModelAndView("file");
        modelAndView.getModel().put("message", "File too large!");
        return modelAndView;
    }
}

5. Tomcatの構成

Tomcatサーバーバージョン7以降にデプロイする場合は、 maxSwallowSize という構成プロパティがあり、設定または変更する必要があります。

このプロパティは、サーバーがファイルを無視することを知っているときに、Tomcatがクライアントからのアップロードのために「飲み込む」最大バイト数を指定します。

プロパティのデフォルト値は2097152(2 MB)です。 変更しない場合、または MultipartResolverで設定した5MBの制限を下回る場合、Tomcatは2 MBを超えるファイルのアップロードを拒否し、カスタム例外処理が呼び出されることはありません。

リクエストが成功し、アプリケーションからのエラーメッセージが表示されるようにするには、maxSwallowSizeプロパティを負の値に設定する必要があります。 これは、ファイルサイズに関係なく、失敗したすべてのアップロードを飲み込むようにTomcatに指示します。

これは、 TOMCAT_HOME / conf /server.xmlファイルで実行されます。

<Connector port="8080" protocol="HTTP/1.1"
  connectionTimeout="20000"
  redirectPort="8443" 
  maxSwallowSize = "-1"/>

6. 結論

この記事では、Springで最大ファイルアップロードサイズを構成する方法と、クライアントがこのサイズ制限を超えるファイルをアップロードしようとしたときに発生するMaxUploadSizeExceededExceptionを処理する方法を示しました。

この記事の完全なソースコードは、GitHubプロジェクトにあります。