1. 概要

以前のチュートリアルでは、フォーム処理の基本を紹介し、SpringMVCのフォームタグライブラリについて説明しました。

このチュートリアルでは、SpringがWebアプリケーションのマルチパート(ファイルアップロード)サポートに提供するものに焦点を当てます。

Springを使用すると、プラグ可能なMultipartResolverオブジェクトを使用してこのマルチパートサポートを有効にできます。 フレームワークは、 CommonsFileUploadで使用するための1つのMultipartResolver実装と、 Servlet3.0マルチパート要求解析で使用するための別の実装を提供します。

MultipartResolver を構成した後、単一のファイルと複数のファイルをアップロードする方法を確認します。

Spring Bootにも触れます。

2. Commons FileUpload

CommonsMultipartResolver を使用してファイルのアップロードを処理するには、次の依存関係を追加する必要があります。

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

これで、Spring構成で CommonsMultipartResolverbeanを定義できます。

このMultipartResolverには、アップロードの最大サイズなどのプロパティを定義するための一連のsetメソッドが付属しています。

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(100000);
    return multipartResolver;
}

ここでは、Bean定義自体でCommonsMultipartResolverのさまざまなプロパティを制御する必要があります。

3. と サーブレット3.0

サーブレット3.0マルチパート解析を使用するには、アプリケーションのいくつかの部分を構成する必要があります。

まず、DispatcherServletregistrationでMultipartConfigElementを設定する必要があります。

public class MainWebAppInitializer implements WebApplicationInitializer {

    private String TMP_FOLDER = "/tmp"; 
    private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; 
    
    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        
        ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(
          new GenericWebApplicationContext()));

        appServlet.setLoadOnStartup(1);
        
        MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, 
          MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
        
        appServlet.setMultipartConfig(multipartConfigElement);
    }
}

MultipartConfigElement オブジェクトでは、保存場所、個々のファイルの最大サイズ、リクエストの最大サイズ(1つのリクエストに複数のファイルがある場合)、およびファイルのアップロードの進行状況がフラッシュされるサイズを構成しました。保管場所へ。

[X183X] CommonsMultipartResolver の場合のように、 Servlet 3.0ではMultipartResolverに登録できないため、これらの設定はサーブレット登録レベルで適用する必要があります。

これが完了すると、StandardServletMultipartResolverをSpring構成に追加できます。

@Bean
public StandardServletMultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

4. ファイルのアップロード

ファイルをアップロードするには、HTML inputタグとtype=’file’を使用する簡単なフォームを作成できます。

選択したアップロード処理構成に関係なく、フォームのエンコーディング属性を multipart /form-dataに設定する必要があります。

これにより、ブラウザはフォームをエンコードする方法を知ることができます。

<form:form method="POST" action="/spring-mvc-xml/uploadFile" enctype="multipart/form-data">
    <table>
        <tr>
            <td><form:label path="file">Select a file to upload</form:label></td>
            <td><input type="file" name="file" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form>

アップロードされたファイルを保存するには、MultipartFile変数を使用できます。

この変数は、コントローラーのメソッド内のリクエストパラメーターから取得できます。

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String submit(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
    modelMap.addAttribute("file", file);
    return "fileUploadView";
}

MultipartFileクラスは、ファイル名、ファイルタイプなど、アップロードされたファイルに関する詳細へのアクセスを提供します。

単純なHTMLページを使用して、この情報を表示できます。

<h2>Submitted File</h2>
<table>
    <tr>
        <td>OriginalFileName:</td>
        <td>${file.originalFilename}</td>
    </tr>
    <tr>
        <td>Type:</td>
        <td>${file.contentType}</td>
    </tr>
</table>

5. アップロード 複数のファイル

1つのリクエストで複数のファイルをアップロードするには、フォーム内に複数の入力ファイルフィールドを配置するだけです。

<form:form method="POST" action="/spring-mvc-java/uploadMultiFile" enctype="multipart/form-data">
    <table>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>

MultipartFile の配列としてアクセスできるように、各入力フィールドの名前が同じであることに注意する必要があります。

@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
public String submit(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
    modelMap.addAttribute("files", files);
    return "fileUploadView";
}

これで、その配列を繰り返し処理して、ファイル情報を表示できます。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>Spring MVC File Upload</title>
    </head>
    <body>
        <h2>Submitted Files</h2>
        <table>
            <c:forEach items="${files}" var="file">    
                <tr>
                    <td>OriginalFileName:</td>
                    <td>${file.originalFilename}</td>
                </tr>
                <tr>
                    <td>Type:</td>
                    <td>${file.contentType}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>

6. 追加のフォームデータを含むファイルのアップロード

アップロードするファイルと一緒にサーバーに追加情報を送信することもできます。

フォームに必須フィールドを含める必要があります。

<form:form method="POST" 
  action="/spring-mvc-java/uploadFileWithAddtionalData"
  enctype="multipart/form-data">
    <table>
        <tr>
            <td>Name</td>
            <td><input type="text" name="name" /></td>
        </tr>
        <tr>
            <td>Email</td>
            <td><input type="text" name="email" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="file" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>

コントローラでは、@RequestParamアノテーションを使用してすべてのフォームデータを取得できます。

@PostMapping("/uploadFileWithAddtionalData")
public String submit(
  @RequestParam MultipartFile file, @RequestParam String name,
  @RequestParam String email, ModelMap modelMap) {

    modelMap.addAttribute("name", name);
    modelMap.addAttribute("email", email);
    modelMap.addAttribute("file", file);
    return "fileUploadView";
}

前のセクションと同様に、JSTLタグ付きのHTMLページを使用して情報を表示できます。

モデルクラスのすべてのフォームフィールドをカプセル化し、コントローラーで@ModelAttributeアノテーションを使用することもできます。 これは、ファイルと一緒に多くの追加フィールドがある場合に役立ちます。

コードを見てみましょう:

public class FormDataWithFile {

    private String name;
    private String email;
    private MultipartFile file;

    // standard getters and setters
}
@PostMapping("/uploadFileModelAttribute")
public String submit(@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) {

    modelMap.addAttribute("formDataWithFile", formDataWithFile);
    return "fileUploadView";
}

7. SpringBootファイルのアップロード

Spring Bootを使用している場合、これまでに見たすべてが引き続き適用されます。

ただし、Spring Bootを使用すると、すべてを簡単に構成して開始できます。

特に、サーブレットを構成する必要はありません。これは、依存関係にWebモジュールが含まれている場合、Bootがサーブレットを登録して構成するためです。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.2</version>
</dependency>

spring-boot-starter-webの最新バージョンはMavenCentralで見つけることができます。

ファイルの最大アップロードサイズを制御する場合は、application.propertiesを編集できます。

spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB

また、ファイルのアップロードを有効にするかどうか、およびファイルのアップロードの場所を制御することもできます。

spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}

$ {java .io.tmpdir} を使用してアップロード場所を定義し、さまざまなオペレーティングシステムで一時的な場所を使用できるようにしたことに注意してください。

8. 結論

この記事では、Springでマルチパートサポートを構成するさまざまな方法について説明しました。 これらを使用して、Webアプリケーションでのファイルのアップロードをサポートできます。

このチュートリアルの実装は、GitHubプロジェクトにあります。 プロジェクトがローカルで実行される場合、フォームの例はhttp:// localhost:8080 / spring-mvc-java/fileUploadでアクセスできます。