プログラミング逆引き辞典

~ 多言語対応のプログラミングレシピ ~

SpringBoot ファイルアップロードのサンプルコード

■①単一ファイルのアップロードの場合

・コントローラークラス

package com.example.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import com.example.form.UploadForm;

/***
 * ファイルアップロードのコントローラークラス
 */
@Controller
public class FileUploadController {

    /**
     * 初期処理
     * @return
     */
    @GetMapping
    String index(Model model) {
        //アップロードファイルをモデルにセット
        model.addAttribute("uploadForm", new UploadForm());

        //アップロード画面に遷移
        return "/index";
    }

    /**
     * ファイルアップロード処理
     * @param uploadForm
     * @return
     */
    @PostMapping("/upload")
    String upload(UploadForm uploadForm) {
        //フォームで渡されてきたアップロードファイルを取得
        MultipartFile multipartFile = uploadForm.getMultipartFile();

        //アップロード実行処理メソッド呼び出し
        uploadAction(multipartFile);

        //リダイレクト
        return "redirect:/";
    }

    /**
     * アップロード実行処理
     * @param multipartFile
     */
    private void uploadAction(MultipartFile multipartFile) {
        //ファイル名取得
        String fileName = multipartFile.getOriginalFilename();

        //格納先のフルパス ※事前に格納先フォルダ「UploadTest」をCドライブ直下に作成しておく
        Path filePath = Paths.get("C:/UploadTest/" + fileName);

        try {
            //アップロードファイルをバイト値に変換
            byte[] bytes  = multipartFile.getBytes();

            //バイト値を書き込む為のファイルを作成して指定したパスに格納
            OutputStream stream = Files.newOutputStream(filePath);

            //ファイルに書き込み
            stream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 
 

・フォームクラス

package com.example.form;

import org.springframework.web.multipart.MultipartFile;

import lombok.Data;

/**
 * ファイルアップロードのフォームクラス
 */
@Data
public class UploadForm {
    private MultipartFile multipartFile;
}

 
 

・画面

<!DOCTYPE html>
<html xmlns:th="https://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>メニュー</title>
</head>
<body>
    <div>
        <!-- /* 「enctype="multipart/form-data"」でアップロードファイルをコントローラークラスに渡す */ -->
        <form th:action="@{/upload}" method="post" enctype="multipart/form-data" th:object="${uploadForm}">
            <div>
                <input type="file" th:field="*{multipartFile}">
            </div>
            <div>
                <input type="submit" value="アップロード">
            </div>
        </form>
    </div>
</body>
</html>

 
 
「multipart/form-data」の詳細はこちらのサイトが非常にわかり易かった
[フロントエンド] multipart/form-dataを理解してみよう
 
 


■②複数ファイルのアップロードの場合

「①単一ファイルのアップロードの場合」を少し変更すればよい
 

【変更内容】

変更1:コントローラークラスに複数ファイルを1つずつにする処理に変更
変更2:フォームクラスのフィールド名の型をリスト型に変更
変更3:画面の入力ボックスに「multiple」を追記
 
 

・コントローラークラス

package com.example.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import com.example.form.UploadForm;

/***
 * ファイルアップロードのコントローラークラス
 */
@Controller
public class FileUploadController {

    /**
     * 初期処理
     * @return
     */
    @GetMapping
    String index(Model model) {
        //アップロードファイルをモデルにセット
        model.addAttribute("uploadForm", new UploadForm());

        //アップロード画面に遷移
        return "/index";
    }

    /**
     * ファイルアップロード処理
     * @param uploadForm
     * @return
     */
    @PostMapping("/upload")
    String upload(UploadForm uploadForm) {
        //フォームで渡されてきたアップロードファイルを取得
        List<MultipartFile> multipartFile = uploadForm.getMultipartFile();

        // ===== 変更1:コントローラークラスに複数ファイルを1つずつにする処理に変更 ===== //
        multipartFile.forEach(e -> {
            //アップロード実行処理メソッド呼び出し
            uploadAction(e);
        });

        //リダイレクト
        return "redirect:/";
    }

    /**
     * アップロード実行処理
     * @param multipartFile
     */
    private void uploadAction(MultipartFile multipartFile) {
        //ファイル名取得
        String fileName = multipartFile.getOriginalFilename();

        //格納先のフルパス ※事前に格納先フォルダ「UploadTest」をCドライブ直下に作成しておく
        Path filePath = Paths.get("C:/UploadTest/" + fileName);

        try {
            //アップロードファイルをバイト値に変換
            byte[] bytes  = multipartFile.getBytes();

            //バイト値を書き込む為のファイルを作成して指定したパスに格納
            OutputStream stream = Files.newOutputStream(filePath);

            //ファイルに書き込み
            stream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 
 

・フォームクラス

package com.example.form;

import java.util.List;

import org.springframework.web.multipart.MultipartFile;

import lombok.Data;

/**
 * ファイルアップロードのフォームクラス
 */
@Data
public class UploadForm {
    // ===== 変更2:フォームクラスのフィールド名の型をリスト型に変更 ===== //
    private List<MultipartFile> multipartFile;
}

 
 

・画面

<!DOCTYPE html>
<html xmlns:th="https://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>メニュー</title>
</head>
<body>
    <div>
        <!-- /* 「enctype="multipart/form-data"」でアップロードファイルをコントローラークラスに渡す */ -->
        <form th:action="@{/upload}" method="post" enctype="multipart/form-data" th:object="${uploadForm}">
            <div>
                <!-- /* ===== 変更3:画面の入力ボックスに「multiple」を追記 ===== */ -->
                <input type="file" th:field="*{multipartFile}" multiple>
            </div>
            <div>
                <input type="submit" value="アップロード">
            </div>
        </form>
    </div>
</body>
</html>