Help us understand the problem. What is going on with this article?

Spring Boot で ダウンロード

More than 1 year has passed since last update.

環境

  • Spring Boot v1.3.0
  • java 8
  • jquery

動機

画面遷移をせずダウンロードしたいが、HttpResponseHeaderクラスを使うのはなんだか気が引けたため、Springパッケージのクラスのみを使って実装。クライアント側の実装も忘れそうなため備忘。

実装

Controller

@RequestMapping("/download")
@ResponseBody
public ResponseEntity<byte[]> download() {
    byte[] data = xxx; // xxx:byte[]形式のオブジェクト

    // ResponseHeader
    HttpHeaders header = new HttpHeaders();
    header.add("Content-Type", "yyy"); // yyy:任意のContent-Type
    header.add("Content-Disposition", "attachment; filename*=utf-8''" + URLEncoder.encode("zzz", "UTF-8")); // zzz:任意のファイル名
    header.add("Set-Cookie", "fileDownload=true; path=/");

    return new ResponseEntity<byte[]>(data, header, HttpStatus.OK);
}
  • Content-Dispositionで強制的にダウンロード、かつ日本語ファイル名に対応。
  • Set-Cookieしてるのはこの後クライアント側で使うため。

javascript

// formのサブミット時にイベント追加
$("#myform").submit(function() {
  startLoading(); // ぐるぐる出す的メソッド
  const COOKIE_KEY_FILEDOWNLOAD = 'fileDownload=';
  var isFileDownload = false;
  // ダウンロード完了まで繰り返す
  var intervalId = setInterval(function() {
    // cookieから fileDownload の取得
    const COOKIES = document.cookie;
    var position = COOKIES.indexOf(COOKIE_KEY_FILEDOWNLOAD);
    if (position >= 0) {
      var startIdx = position + COOKIE_KEY_FILEDOWNLOAD.length;
      var endIdx = COOKIES.indexOf(';', startIdx);
      if (endIdx < 0) {
        endIdx = COOKIES.length;
      }
      isFileDownload = decodeURIComponent(COOKIES.substring(startIdx, endIdx)) == 'true';
    }
    // fileDownloadがtrueなら繰り返し終了
    if (isFileDownload) {
      clearInterval(intervalId);
      var date = new Date();
      date.setTime(date.getTime() - 1);
      document.cookie = COOKIE_KEY_FILEDOWNLOAD + 'false; path=/; max-age=0';
      stopLoading(); // ぐるぐるやめる的メソッド
    }
  }, 500);
});
  • Set-Cookieされた値を参照することでダウンロード成功時にぐるぐるを止めるようにしている。

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away