Spring Boot 4 で作成したファイルダウンロード画面。「ダウンロード」ボタン押下で DB を読んで CSV ファイルを生成し、そのファイルがクライアントPCにダウンロードされる。
// ボタン押下で実行される処理
@PostMapping("/createFile")
public ResponseEntity<Resource> downloadFile() throws Exception {
Path path = HogeService.make_file_path(); // ダウンロードされるファイルを作成するパス
HogeService.logic_make(path.toString()); // ダウンロードファイルを作成
Resource resource = new FileSystemResource(path);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
return ResponseEntity.ok()
.contentType(getContentType(path))
.contentLength(resource.contentLength())
.headers(headers)
.body(resource);
}
// ContentType の取得
private MediaType getContentType(Path path) throws IOException {
try {
return MediaType.parseMediaType(Files.probeContentType(path));
}
catch (IOException e) {
return MediaType.APPLICATION_OCTET_STREAM;
}
}
しかし、例えばダウンロードに失敗したときは Web 画面上にエラーメッセージを表示したいとか、成功したら画面に「正常にダウンロードできました」などと表示したい場合はこれではダメだ。
上の例のようにデータ(ダウンロードファイル)を出力するか(ダウンロード)、HTML を出力するか(画面表示)、生のテキストや JSON データなどを出力するか(API など)・・・のいずれかひとつのことしかできない。
「先にファイルを出力して、その次に結果を伝える HTML を出力する」という二段構えの出力はできない。ファイルを出力すれば画面(HTML)は表示できないし、画面(HTML)を表示(出力)すればファイルは出力できない。