LoginSignup
12

More than 5 years have passed since last update.

Spring Boot で ダウンロード

Posted at

環境

  • 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された値を参照することでダウンロード成功時にぐるぐるを止めるようにしている。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12