はじめに
Spring Bootでファイルサーバ(もどき)を実装するため、ディレクトリごとアップロードする処理を作成する。
環境
- Java 17
- Spring Boot 2.7.4
- Google Chrome 106
※ブラウザによって挙動が変わる可能性があります。
実装
フロントエンド側
<form action="" method="post" enctype="multipart/form-data">
<input type="file" id="filepicker" name="dirFileList" webkitdirectory multiple />
<input type="submit" value="アップロード" />
</form>
<input>
タグにwebkitdirectory
を利用する。非標準機能だが大抵のモダンブラウザは大丈夫なはず。
また、ファイルをアップロードするために<form>
タグにはmethod="post" enctype="multipart/form-data"
を指定しておく。
バックエンド側
private final String DST_ROOT = "C:\\tmp\\files-demo\\output";
@PostMapping
public String upload(@RequestParam List<MultipartFile> dirFileList) throws IOException, IllegalStateException {
for (var mpf : dirFileList) {
final Path dst = Paths.get(DST_ROOT, mpf.getOriginalFilename());
// Debug
System.out.println(String.format("%s -> %s", mpf.getOriginalFilename(), dst));
final Path parent = dst.getParent();
if (Files.notExists(parent)) {
Files.createDirectories(parent);
}
mpf.transferTo(dst);
}
return "post-upload";
}
multipart/form-data
で送信されたアップロードファイルはMultipartFile
を介して扱うことができる。ただし今回は複数ファイルになる可能性があるのでリストで受ける。
Chromeの場合は 選択したディレクトリ名を含む相対パスがMultipartFile.getOriginalFilename
で取得できる。
└─demo
│ memo.txt
│ 日本語.txt
│
└─sub
sub-file.txt
↓(demo
ディレクトリを選択)
dirFileList.forEach(mpf -> System.out.println(mpf.getOriginalFilename()));
/* ↓
demo/memo.txt
demo/日本語.txt
demo/sub/sub-file.txt
*/
アップロードファイルはMultipartFile.transferTo
を利用することで簡単にサーバローカルに保存することができる。
ただし親ディレクトリは作られないので事前にcreateDirectories
しておく必要がある。