1. 概要

Apache Commons File Upload Library は、 multipart /form-dataコンテンツタイプを使用してHTTPプロトコル経由で大きなファイルをアップロードするのに役立ちます。

このクイックチュートリアルでは、Springと統合する方法を見ていきます。

2. Mavenの依存関係

ライブラリを使用するには、commons-fileuploadアーティファクトが必要です。

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

最新バージョンはMavenCentralにあります。

3. 一度に転送

デモンストレーションの目的で、ファイルペイロードを使用してController処理リクエストを作成します。

@PostMapping("/upload")
public String handleUpload(HttpServletRequest request) throws Exception {
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);

    DiskFileItemFactory factory = new DiskFileItemFactory();
    factory.setRepository(
      new File(System.getProperty("java.io.tmpdir")));
    factory.setSizeThreshold(
      DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
    factory.setFileCleaningTracker(null);

    ServletFileUpload upload = new ServletFileUpload(factory);

    List items = upload.parseRequest(request);

    Iterator iter = items.iterator();
    while (iter.hasNext()) {
        FileItem item = iter.next();

        if (!item.isFormField()) {
            try (
              InputStream uploadedStream = item.getInputStream();
              OutputStream out = new FileOutputStream("file.mov");) {

                IOUtils.copy(uploadedStream, out);
            }
        }
    }    
    return "success!";
}

最初に、ライブラリのServletFileUploadクラスにあるisMultipartContentメソッドを使用して、リクエストにマルチパートコンテンツが含まれているかどうかを確認する必要があります。

デフォルトでは、Springは MultipartResolver を備えており、このライブラリを使用するには無効にする必要があります。それ以外の場合は、リクエストの内容を読み取りますコントローラーに到達する前。

これは、application.propertiesファイルにこの構成を含めることで実現できます。

spring.http.multipart.enabled=false

これで、ファイルを保存するディレクトリ、ライブラリがディスクへの書き込みを決定するしきい値、およびリクエストの終了後にファイルを削除する必要があるかどうかを設定できます。

ライブラリはDiskFileItemFactoryクラスを提供し、はファイルの保存とクリーニングの構成を担当します。 setRepository メソッドは、ターゲットディレクトリを設定します。デフォルトは、例に示されています。

次に、setSizeThresholdは最大ファイルサイズを設定します。

次に、 setFileCleaningTracker メソッドがあります。このメソッドは、nullに設定すると、一時ファイルは変更されません。 デフォルトでは、リクエストが終了した後にそれらを削除します

これで、実際のファイル処理に進むことができます。

まず、以前に作成したファクトリを含めて、ServletFileUploadを作成します。 次に、リクエストの解析に進み、フォームフィールドのライブラリの主な抽象化であるFileItemのリストを生成します。

正規形フィールドではないことがわかっている場合は、 InputStream を抽出し、 IOUtils から便利なコピーメソッドを呼び出します(その他のオプションについては、こちらをご覧ください)。 このチュートリアル)

これで、ファイルが必要なフォルダーに保存されました。 これは通常、ファイルに簡単にアクセスできるため、この状況を処理するためのより便利な方法ですが、時間/メモリの効率も最適ではありません。

次のセクションでは、ストリーミングAPIを見ていきます。

4. ストリーミングAPI

ストリーミングAPIは使いやすく、一時的な場所にコピーしないだけで大きなファイルを処理するのに最適な方法です。

ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterStream = upload.getItemIterator(request);
while (iterStream.hasNext()) {
    FileItemStream item = iterStream.next();
    String name = item.getFieldName();
    InputStream stream = item.openStream();
    if (!item.isFormField()) {
        // Process the InputStream
    } else {
        String formFieldValue = Streams.asString(stream);
    }
}

前のコードスニペットでは、DiskFileItemFactoryが含まれていないことがわかります。 これは、ストリーミングAPIを使用する場合、は必要ないためです。

次に、フィールドを処理するために、ライブラリは FileItemIterator を提供します。これは、nextメソッドを使用してリクエストからフィールドを抽出するまで何も読み取りません。

最後に、他のフォームフィールドの値を取得する方法を確認できます。

5. 結論

この記事では、SpringでApacheCommonsファイルアップロードライブラリを使用して大きなファイルをアップロードおよび処理する方法を確認しました。

いつものように、完全なソースコードはGitHubにあります。