- Spring
Spring Bootファイルダウンロード|CSV・日本語名・大容量
Spring Boot でファイルをダウンロードさせるには、コントローラーから ResponseEntity<Resource> を返し、Content-Disposition: attachment ヘッダーを付けます。 日本語のファイル名は、ContentDisposition.attachment().filename(名前, StandardCharsets.UTF_8) で作ると、RFC 6266・RFC 5987 の filename* 形式になり、ブラウザで化けません。
@GetMapping("/files/{id}")
public ResponseEntity<Resource> download(@PathVariable long id) {
StoredFile f = fileService.find(id); // DB から保存先と表示名を引く
Resource body = new FileSystemResource(f.path());
ContentDisposition cd = ContentDisposition.attachment()
.filename(f.displayName(), StandardCharsets.UTF_8) // 日本語名は charset を必ず指定
.build();
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, cd.toString())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(body);
}
売上一覧_2026年10月.csv のとき、実際に出るヘッダーは次のとおりです。
Content-Disposition: attachment; filename="_____2026_10_.csv"; filename*=UTF-8''%E5%A3%B2%E4%B8%8A%E4%B8%80%E8%A6%A7_2026%E5%B9%B410%E6%9C%88.csv
| やりたいこと | 書き方 | この記事の節 |
|---|---|---|
| 保存済みのファイルを返す | ResponseEntity<Resource> + FileSystemResource |
基本形 |
| 日本語のファイル名 | filename(名前, StandardCharsets.UTF_8) |
日本語ファイル名 |
| Excel で開ける CSV | 先頭に BOM を付けた UTF-8(または Windows-31J) | CSV |
| 数十万行の CSV・大きなファイル | StreamingResponseBody |
大容量 |
| 動画などの途中から再生・再開 | Resource を返すだけで Range(206)に対応 |
Range |
../ で別のファイルを取られない |
ID で引く。パスなら normalize() と startsWith |
セキュリティ |
確認環境:Spring Boot 4.1.1(Spring Framework 7.0.9)、OpenJDK 25.0.4.1(Linux)。ContentDisposition と HttpRange は、Spring Framework v7.0.9 のソースから spring-core・spring-web の必要なクラスをビルドして実際に動かし、この記事のヘッダーの文字列と Range の結果を取りました。CSV の文字コードとパスの判定は JDK 25 で動かしています。コントローラーが Range を処理する流れは v7.0.9 の AbstractMessageConverterMethodProcessor のソースとリファレンス、ブラウザの扱いは RFC 6266 と MDN に基づきます(確認日 2026年10月13日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Spring Bootファイルダウンロード|CSV・日本語名・大容量」
基本形:ResponseEntity を返す
package com.example.demo.file;
import java.nio.charset.StandardCharsets;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FileDownloadController {
private final FileService fileService;
public FileDownloadController(FileService fileService) {
this.fileService = fileService;
}
@GetMapping("/files/{id}")
public ResponseEntity<Resource> download(@PathVariable long id) {
StoredFile f = fileService.findForCurrentUser(id); // 見つからない・権限が無ければ 404
Resource body = new FileSystemResource(f.path());
MediaType type = MediaTypeFactory.getMediaType(f.displayName())
.orElse(MediaType.APPLICATION_OCTET_STREAM);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
ContentDisposition.attachment()
.filename(f.displayName(), StandardCharsets.UTF_8)
.build().toString())
.contentType(type)
.body(body);
}
}
| 部品 | 役割 |
|---|---|
Resource |
中身の入れ物。FileSystemResource(ファイル)・ByteArrayResource(メモリ上のバイト列)・ClassPathResource(jar の中)など |
ContentDisposition.attachment() |
「画面に表示せず保存させる」指示。inline() にするとブラウザで開く(PDF・画像) |
MediaTypeFactory.getMediaType |
拡張子から Content-Type を決める(.csv → text/csv、.pdf → application/pdf) |
Content-Length |
Resource の長さから Spring が自動で付ける |
Resource を返すと、Spring は中身をメモリに読み込まずに、少しずつレスポンスへ書き出します。 大きなファイルでも FileSystemResource ならそのまま返せます。byte[] を返す形は、全部をメモリに載せるため小さいファイル向けです。
日本語ファイル名:ContentDisposition が出すヘッダー
filename(名前, StandardCharsets.UTF_8) と charset を指定すると、filename(ASCII だけの代わりの名前)と filename*(UTF-8 をパーセントエンコードした本当の名前)の両方が出ます。 Spring Framework 7.0.9 の ContentDisposition で、実際に出た文字列です。
| 名前 | filename(名前, UTF_8) の結果 |
|---|---|
report.csv |
attachment; filename="report.csv"; filename*=UTF-8''report.csv |
売上一覧_2026年10月.csv |
attachment; filename="_____2026_10_.csv"; filename*=UTF-8''%E5%A3%B2%E4%B8%8A%E4%B8%80%E8%A6%A7_2026%E5%B9%B410%E6%9C%88.csv |
請求書 #12 100%.pdf |
attachment; filename="___ #12 100%.pdf"; filename*=UTF-8''%E8%AB%8B%E6%B1%82%E6%9B%B8%20#12%20100%25.pdf |
my report (1).csv |
attachment; filename="my report (1).csv"; filename*=UTF-8''my%20report%20%281%29.csv |
a"b.csv |
attachment; filename="a\"b.csv"; filename*=UTF-8''a%22b.csv |
a;b,c.csv |
attachment; filename="a;b,c.csv"; filename*=UTF-8''a%3Bb%2Cc.csv |
café.txt |
attachment; filename="cafe.txt"; filename*=UTF-8''caf%C3%A9.txt |
😀.txt |
attachment; filename="_.txt"; filename*=UTF-8''%F0%9F%98%80.txt |
filename の側は、ASCII にできない文字が _ に置き換わり、é のようなアクセント付きの文字は e になります。 filename* を読めないクライアントだけが、こちらを使います。
charset を付けないと、日本語がそのままヘッダーに入ります。
| 名前 | filename(名前)(charset なし)の結果 |
|---|---|
売上一覧_2026年10月.csv |
attachment; filename="売上一覧_2026年10月.csv" |
HTTP のヘッダーは ASCII を前提にしており(RFC 9110)、ASCII 以外の文字がどう送られ、どう読まれるかはサーバーとブラウザによって変わります。化ける原因はほとんどがこの形です。日本語の名前には必ず StandardCharsets.UTF_8 を付けます。
ブラウザはどちらを使うか
RFC 6266 は、filename と filename* が両方あるとき、filename* を理解できる受け手は filename* を使うよう定めています。MDN にも「filename* is preferred over filename when both are understood」とあり、両方を付けることを勧めています。Spring の ContentDisposition は、この勧めどおりの形を出します。
| 書き方 | 問題 |
|---|---|
URLEncoder.encode(name, UTF_8) の結果を filename="…" に入れる |
空白が + になる。filename の中のパーセントエンコードは、MDN によると Firefox と Chrome はデコードし Safari はしない |
new String(name.getBytes("UTF-8"), "ISO-8859-1") を入れる |
ブラウザごとに解釈が違い、化けることがある |
ContentDisposition…filename(name, UTF_8) |
RFC 6266 の形。filename* を優先して使う |
ファイル名の / や \ は、ブラウザ側で _ などに置き換えられることがあります(MDN)。
fetch で受けてファイル名を取り出す(SPA)
const res = await fetch(`/files/${id}`, { credentials: "same-origin" });
const blob = await res.blob();
const cd = res.headers.get("Content-Disposition") ?? "";
const star = cd.match(/filename\*=UTF-8''([^;]+)/i);
const plain = cd.match(/filename="([^"]+)"/i);
const name = star ? decodeURIComponent(star[1]) : plain ? plain[1] : "download";
const url = URL.createObjectURL(blob);
const a = Object.assign(document.createElement("a"), { href: url, download: name });
a.click();
URL.revokeObjectURL(url);
別オリジンの API から受けるときは、Content-Disposition を JavaScript から読めるように公開します。 CORS の既定では、このヘッダーは res.headers.get で読めません。
config.setExposedHeaders(List.of(HttpHeaders.CONTENT_DISPOSITION));
CORS の設定の全体は関連記事「Spring Boot CORS設定|3つの書き方とSecurity併用のコード全文」で扱っています。
CSV をダウンロードさせる(Excel で化けない)
Excel は、BOM の無い UTF-8 の CSV を開くと、日本語が化けることがあります。 対策は2つです。
| 方法 | 長所 | 短所 |
|---|---|---|
BOM 付き UTF-8(先頭に EF BB BF) |
すべての文字を表せる。絵文字・外字も可 | BOM を知らないツールでは先頭に余計な文字が入る |
| Windows-31J(MS932) | 既存の業務システムに取り込みやすい | 表せない文字がある(下の表) |
BOM 付き UTF-8 で作る(小さい CSV)
@GetMapping("/reports/sales.csv")
public ResponseEntity<Resource> salesCsv() {
StringBuilder sb = new StringBuilder(""); // BOM(UTF-8 で EF BB BF になる)
sb.append("日付,商品,金額\r\n");
for (Sale s : salesService.findThisMonth()) {
sb.append(csv(s.date().toString())).append(',')
.append(csv(s.itemName())).append(',')
.append(s.amount()).append("\r\n");
}
byte[] bytes = sb.toString().getBytes(StandardCharsets.UTF_8);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment()
.filename("売上_" + YearMonth.now() + ".csv", StandardCharsets.UTF_8).build().toString())
.contentType(new MediaType("text", "csv", StandardCharsets.UTF_8))
.body(new ByteArrayResource(bytes));
}
JDK 25 で、BOM と2行を UTF-8 で書いたときの先頭のバイトは EF BB BF、全体は31バイトでした(BOM 3 バイト+本文 28 バイト)。
CSV の値の書き方(区切り・改行・数式)
/** CSV の1項目を作る。区切り・引用符・改行と、Excel の数式として動く先頭文字を処理する */
static String csv(String v) {
if (v == null) return "";
if (!v.isEmpty() && "=+-@\t\r".indexOf(v.charAt(0)) >= 0) {
v = "'" + v; // 数式として実行させない
}
if (v.contains(",") || v.contains("\"") || v.contains("\n") || v.contains("\r") || v.startsWith("'")) {
v = "\"" + v.replace("\"", "\"\"") + "\""; // 引用符は2つ重ねる
}
return v;
}
利用者が入力した文字を CSV に出すときは、=・+・-・@ で始まる値に注意します。 Excel で開くと数式として動くことがあるためです(CSV インジェクション。OWASP の「CSV Injection」で解説)。先頭に ' を付けると文字列として表示されます。ただし数値のマイナス(-100)にも ' が付くため、数値の列にはこの処理を通さないようにします。
Windows-31J で作るとき
Java の "Shift_JIS" と "windows-31j"(MS932)は、表せる文字が違います。JDK 25 の CharsetEncoder.canEncode で確かめた結果です。
| 文字 | Shift_JIS |
windows-31j |
|---|---|---|
髙(はしごだか) |
表せない | 表せる |
①・㈱ |
表せない | 表せる |
~(全角チルダ U+FF5E) |
表せない | 表せる |
−(マイナス記号 U+2212) |
表せる | 表せない |
🍣(絵文字) |
表せない | 表せない |
getBytes("windows-31j") は、表せない文字を黙って ? に置き換えます(🍣 を変換して戻すと ? でした)。名前に外字や絵文字が入りうるなら、BOM 付き UTF-8 にするか、CharsetEncoder でエラーにして気づけるようにします。Windows 向けには "Shift_JIS" ではなく "windows-31j" を使います。
CharsetEncoder enc = Charset.forName("windows-31j").newEncoder()
.onUnmappableCharacter(CodingErrorAction.REPORT); // 表せない文字で例外にする
Excel で CSV を開くときの化けの原因は関連記事「文字化けの原因と直し方|CSVをExcelで開くときの対策」で、Java での CSV の読み書きは関連記事「Java CSV読み込み・書き込み入門|文字化けを防ぐBOMと文字コード」で扱っています。仕様の決め方は関連記事「CSV出力・取込の仕様設計|文字コード・BOMとエラーチェック一覧」で扱っています。
大容量:StreamingResponseBody で少しずつ書く
数十万行の CSV を StringBuilder で作ると、全部がメモリに載ります。StreamingResponseBody を返すと、DB から読みながらレスポンスへ書き出せます。
@GetMapping("/reports/orders.csv")
public ResponseEntity<StreamingResponseBody> ordersCsv() {
StreamingResponseBody body = out -> {
Writer w = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
w.write('');
w.write("注文ID,顧客,金額,注文日時\r\n");
jdbcTemplate.query(
"select id, customer_name, amount, ordered_at from orders order by id",
rs -> { // 1行ずつ呼ばれる(RowCallbackHandler)
try {
w.write(rs.getLong(1) + "," + csv(rs.getString(2)) + ","
+ rs.getBigDecimal(3) + "," + rs.getTimestamp(4).toLocalDateTime() + "\r\n");
}
catch (IOException e) {
throw new UncheckedIOException(e);
}
});
w.flush();
};
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment()
.filename("注文一覧.csv", StandardCharsets.UTF_8).build().toString())
.contentType(new MediaType("text", "csv", StandardCharsets.UTF_8))
.body(body);
}
| 注意点 | 内容 |
|---|---|
| 別のスレッドで動く | StreamingResponseBody は Spring MVC の非同期処理として、リクエストのスレッドとは別のスレッドで書かれる(Spring Framework のリファレンス「Asynchronous Requests」) |
| トランザクション | コントローラーの @Transactional は、書き出しのスレッドまで続かない。上の例の jdbcTemplate.query は、書き出しのスレッドで接続を取って閉じる |
JPA の Stream |
リポジトリの Stream<Order> は開いたトランザクションの中で使う必要がある。書き出しのラムダの中で TransactionTemplate を使う |
| タイムアウト | 非同期の既定のタイムアウトは、Tomcat では 30 秒(Servlet 仕様の既定)。長い出力は spring.mvc.async.request-timeout を延ばす |
| 途中のエラー | 書き始めた後はステータス 200 を変えられない。途中で失敗すると、ファイルが途中で切れる |
Content-Length |
分からないので付かない(チャンク形式で送られる)。ブラウザの進捗表示は残り時間が出ない |
spring:
mvc:
async:
request-timeout: 10m
ファイルとして保存済みのものは、StreamingResponseBody にしなくても FileSystemResource で足ります。 Resource もメモリに全部は載せず、Content-Length と Range にも対応するためです。StreamingResponseBody は、その場で中身を作るときに使います。
Range(途中から・再開のダウンロード)
コントローラーが Resource か ResponseEntity<Resource> を返すと、Spring MVC が Range ヘッダーを自動で処理し、206 Partial Content を返します。 Spring Framework 7.0.9 のソースでは、次の条件で動きます。
| 条件 | 内容 |
|---|---|
| 返す型 | Resource(InputStreamResource を除く) |
| ステータス | 200 のとき(ResponseEntity.ok()) |
| レスポンスヘッダー | 常に Accept-Ranges: bytes が付く |
| 範囲が不正 | 416 と Content-Range: bytes */〈全体の長さ〉 |
HttpRange を動かして、1000 バイトのリソースに対する範囲の結果を取りました。
| Range ヘッダー | 返る部分(開始位置+長さ) |
|---|---|
bytes=0-99 |
0+100 |
bytes=900- |
900+100 |
bytes=-100(末尾から) |
900+100 |
bytes=0-99,200-299 |
0+100 と 200+100(multipart で返る) |
bytes=990-2000(はみ出し) |
990+10(末尾までに切り詰め) |
bytes=1000- |
エラー:'position' exceeds the resource length 1000(→ 416) |
| 101 個の範囲 | エラー:Too many ranges: 101(上限は 100) |
InputStreamResource は長さが分からないため、Range に対応しません。 動画の途中から再生などをさせたいときは、FileSystemResource や PathResource を返します。
セキュリティ:パストラバーサルと権限
// NG:利用者が送った名前をそのままパスにつなげる
@GetMapping("/download")
public Resource bad(@RequestParam String name) {
return new FileSystemResource("/srv/app/files/" + name); // name=../../etc/passwd で外のファイルが読める
}
一番安全なのは、利用者にはファイルの ID だけを渡し、保存先のパスは DB から引く形です。 冒頭の fileService.findForCurrentUser(id) のように、「そのユーザーが見てよいファイルか」も同じ場所で確かめます。
どうしても名前で受けるときは、正規化した後に、決めたフォルダの中かどうかを Path で確かめます。
private static final Path BASE = Path.of("/srv/app/files").toAbsolutePath().normalize();
static Path safeResolve(String name) {
Path p = BASE.resolve(name).normalize();
if (!p.startsWith(BASE) || p.equals(BASE)) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
return p;
}
JDK 25 で、いろいろな名前を判定した結果です。
| 送られた名前 | 正規化後 | 判定 |
|---|---|---|
report.csv |
/srv/app/files/report.csv |
OK |
2026/10/report.csv |
/srv/app/files/2026/10/report.csv |
OK |
../../etc/passwd |
/srv/etc/passwd |
拒否 |
../files-secret/a.csv |
/srv/app/files-secret/a.csv |
拒否 |
/etc/passwd(絶対パス) |
/etc/passwd |
拒否 |
a/../../files/report.csv |
/srv/app/files/report.csv |
OK(中に戻っている) |
.. |
/srv/app |
拒否 |
String の startsWith で比べると、/srv/app/files-secret/a.csv が /srv/app/files で始まると判定されます(true)。Path の startsWith は階層単位で比べるため false になります。必ず Path 同士で比べます。
| 対策 | 理由 |
|---|---|
| ID で引き、パスは DB に持つ | 利用者がパスを指定できない |
| ログイン中のユーザーの権限を確かめる | ID を1つずつ変えて他人のファイルを取られるのを防ぐ |
| 表示名と保存名を分ける | 保存名は UUID などにし、表示名は Content-Disposition にだけ使う |
X-Content-Type-Options: nosniff |
ブラウザが中身から種類を推測して HTML として開くのを防ぐ(Spring Security は既定で付ける) |
inline は種類を限る |
利用者が上げた HTML・SVG を inline で返すと、同じオリジンでスクリプトが動く |
アップロード側の対策は関連記事「ファイルアップロードのセキュリティ対策|実装コードと検証チェックリスト」で扱っています。保存先の決め方は関連記事「ファイルアップロードの保存先設計|DBかストレージかの判断表と命名規則」で扱っています。
そのほかの返し方
| 返し方 | 向いている場面 | 注意 |
|---|---|---|
ResponseEntity<Resource> |
ほとんどの場合(おすすめ) | - |
ResponseEntity<byte[]> |
数 MB までのその場で作るファイル | 全部がメモリに載る |
ResponseEntity<StreamingResponseBody> |
大きな CSV など、その場で作るもの | 別スレッド・タイムアウト |
HttpServletResponse に直接書く |
Spring 以前の書き方の移植 | ヘッダーとステータスを自分で全部管理する。Range は自分で書く |
静的リソース(/static) |
誰でも取れる固定のファイル | 権限の確認ができない |
ZIP にまとめて返すときは、StreamingResponseBody の中で ZipOutputStream に書きます。ZIP の中の日本語のファイル名は関連記事「Java ZIP圧縮・解凍の書き方|ディレクトリごと圧縮と日本語名の文字化け対策」で扱っています。アップロードの実装は関連記事「Spring Bootファイルアップロード|MultipartFile実装コード全文」で扱っています。
テストで確かめる(MockMvc)
@WebMvcTest(FileDownloadController.class)
class FileDownloadControllerTest {
@Autowired MockMvc mvc;
@MockitoBean FileService fileService;
@Test
void 日本語のファイル名がfilenameStarで返る(@TempDir Path dir) throws Exception {
Path file = Files.writeString(dir.resolve("x.csv"), "a,b\r\n");
given(fileService.findForCurrentUser(1L)).willReturn(new StoredFile(file, "売上.csv"));
mvc.perform(get("/files/1"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"__.csv\"; filename*=UTF-8''%E5%A3%B2%E4%B8%8A.csv"))
.andExpect(header().string(HttpHeaders.ACCEPT_RANGES, "bytes"));
}
@Test
void Rangeを付けると206(@TempDir Path dir) throws Exception {
Path file = Files.write(dir.resolve("x.bin"), new byte[1000]);
given(fileService.findForCurrentUser(1L)).willReturn(new StoredFile(file, "x.bin"));
mvc.perform(get("/files/1").header(HttpHeaders.RANGE, "bytes=0-99"))
.andExpect(status().isPartialContent())
.andExpect(header().string(HttpHeaders.CONTENT_RANGE, "bytes 0-99/1000"));
}
}
StreamingResponseBody を返すメソッドは非同期処理になるため、MockMvc では asyncDispatch(mvc.perform(...).andReturn()) で結果を取ります。テストの書き方は関連記事「Spring Bootテスト入門|@WebMvcTestとMockMvcの使い分け」で扱っています。
よくある質問
Q. ダウンロードされず、ブラウザに中身が表示されます。
A. Content-Disposition が付いていないか inline になっています。attachment にします。CSV を text/plain で返すとブラウザが表示することがあるため、text/csv か application/octet-stream にします。
Q. Safari だけファイル名が化けます。
A. filename の側にパーセントエンコードした文字列を入れていないかを確かめます。MDN によると Safari は filename の中のパーセントエンコードをデコードしません。ContentDisposition.filename(名前, UTF_8) を使い、filename* に入れます。
Q. 大きなファイルで OutOfMemoryError になります。
A. byte[] や Files.readAllBytes で全部を読んでいないかを確かめます。保存済みのファイルなら FileSystemResource を返し、その場で作るなら StreamingResponseBody で書きます。
Q. ダウンロードの途中で切れます。
A. StreamingResponseBody なら非同期のタイムアウト(Tomcat の既定は 30 秒)を疑います。spring.mvc.async.request-timeout を延ばします。ロードバランサーやリバースプロキシのタイムアウトも確かめます。
まとめ
- 基本は
ResponseEntity<Resource>+Content-Disposition: attachment - 日本語名は
ContentDisposition.attachment().filename(名前, StandardCharsets.UTF_8)。filename*=UTF-8''…が出る - charset を付けないと日本語がそのままヘッダーに入り、化ける原因になる
- Excel 向けの CSV は BOM 付き UTF-8。Windows-31J は表せない文字が
?になる - その場で作る大きなファイルは
StreamingResponseBody。別スレッドとタイムアウトに注意 Resourceを返せば Range(206)は自動。InputStreamResourceは対象外- ファイルは ID で引き、名前で受けるなら
Pathのnormalize()とstartsWith
参考・出典
確認日はいずれも 2026年10月13日です。
- Spring Framework リファレンス「Range Requests」:https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-range.html
- Spring Framework リファレンス「Asynchronous Requests」:https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-ann-async.html
- Spring Framework ソースコード(v7.0.9)ContentDisposition:https://github.com/spring-projects/spring-framework/blob/v7.0.9/spring-web/src/main/java/org/springframework/http/ContentDisposition.java
- Spring Framework ソースコード(v7.0.9)HttpRange:https://github.com/spring-projects/spring-framework/blob/v7.0.9/spring-web/src/main/java/org/springframework/http/HttpRange.java
- Spring Framework ソースコード(v7.0.9)AbstractMessageConverterMethodProcessor:https://github.com/spring-projects/spring-framework/blob/v7.0.9/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java
- RFC 6266 Use of the Content-Disposition Header Field in HTTP:https://www.rfc-editor.org/rfc/rfc6266
- RFC 5987 Character Set and Language Encoding for HTTP Header Field Parameters:https://www.rfc-editor.org/rfc/rfc5987
- MDN「Content-Disposition」:https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Disposition
- Apache Tomcat 11 Configuration Reference「The HTTP Connector」:https://tomcat.apache.org/tomcat-11.0-doc/config/http.html
- OWASP「CSV Injection」:https://owasp.org/www-community/attacks/CSV_Injection
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Spring Bootファイルダウンロード|CSV・日本語名・大容量」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。