保存ダイアログを表示させてファイルをダウンロードさせる方法

公開日: : Java

例えば、ブラウザに表示している画像は右クリックを使ってダウンロードできますが、左クリックから保存ダイアログを使ってダウンロードさせることもできます。

画像の大きさをリサイズするサービス Resizer では、この方法でリサイズした画像をダウンロードさせています。

この方法の実装方法をメモしておきます。

icatch-10139609144_5bc33706f9_z

photo credit: All rights reserved by Dell’s Official Flickr Page

目次

1. レスポンスのコンテントタイプとヘッダを設定する

画像や zip などのコンテンツをダウンロードさせるには、コンテントタイプ(Content-Type)に “application/octet-stream” を設定したレスポンスを返してやります。

“application/octet-stream” が設定されていると、多くのブラウザは「このコンテンツをダウンロードしますか?」とダイアログを表示させる実装になっているそうです。
なので、この仕組みを使ってコンテンツを自分のマシンにとり込んでしまうというわけです。

項目はコンテントタイプ以外にもヘッダに次のものを設定します。

  • コンテンツの名称
  • コンテンツのサイズ(容量)

コンテンツの名称はたいていの場合ファイル名になると思います。
ダウンロードさせる画像ファイルや zip ファイルなどの名称をそのまま設定すれば OK です。

コンテンツのサイズはダウンロードさせるコンテンツの容量になります。
単位はバイトです。

2. Java によるサンプルソースコード

Java でこの処理を行うサンプルを書いてみました。
他の言語でもやることは変わらないと思うので、参考にはなるんじゃないかと思います。

/**
 * コンテンツ({@code File} オブジェクト)をダウンロードする。
 * 
 * @param response コンテンツをダウンロードするのに使用する {@code HttpServletResponse} オブジェクト
 * @param file ダウンロードするコンテンツを格納した {@code File} オブジェクト
 * @throws FileNotFoundException 画像ファイルが存在しなかった場合
 * @throws IOException 画像ファイルの読み書きに失敗した場合
 */
public void download(HttpServletResponse response, File file) throws FileNotFoundException, IOException {
    setUpResponseForDownload(response, file);

    copyFileToResponse(response, new FileInputStream(file));
}

/**
 * コンテンツをダウンロードする際のレスポンスを設定する。
 * 
 * 次をレスポンスとヘッダに設定する。
 * 
 * <ul>
 * <li>ContentType に "application/octet-stream" を設定</li>
 * <li>Header にコンテンツの名称を設定</li>
 * <li>Header にコンテンツのサイズ(容量)を設定</li>
 * </ul>
 * 
 * @param response コンテンツをダウンロードするのに使用する {@code HttpServletResponse} オブジェクト
 * @param file ダウンロードするコンテンツを格納した {@code File} オブジェクト
 */
private void setUpResponseForDownload(HttpServletResponse response, File file) {
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
    response.setHeader("Content-Length", String.valueOf(FileUtils.sizeOf(file)));
}

/**
 * コンテンツをレスポンスに設定する。
 * 
 * @param response コンテンツをダウンロードするのに使用する {@code HttpServletResponse} オブジェクト
 * @param inputStream ダウンロードするコンテンツの {@code InputStream} オブジェクト
 * @throws FileNotFoundException 画像ファイルが存在しなかった場合
 * @throws IOException 画像ファイルの読み書きに失敗した場合
 */
private void copyFileToResponse(HttpServletResponse response,
        InputStream inputStream) throws IOException, FileNotFoundException {
    IOUtils.copy(inputStream, response.getOutputStream());
}

コンテンツのサイズ(容量)を計算する方法として Commons IOFileUtils#sizeOf メソッドを使っています。

同様に、コンテンツをレスポンスにセットする方法として [IOUtils#copy](http://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html#copy(java.io.InputStream, java.io.OutputStream)) メソッドを使っています。

Commons IO には、ファイルを扱う際のちょっとした処理がたくさん定義されています。
工数を削減するためにも、どういうものが用意されているのか一度ざっと見ておくことをおすすめします。

3. まとめ

保存ダイアログを表示してファイル(コンテンツ)をダウンロードさせる方法のまとめです。

  • コンテントタイプに “application/octet-stream” を設定する
  • ヘッダにコンテンツの名称を設定する
  • ヘッダにコンテンツのサイズ(容量)を設定する

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch_2185253176-resized

Java8 の Optional 型を返す Generics を使ったメソッドを定義する

Java8 の Optional とガード節 に続いて Java8 の Optional ネタ。今回

記事を読む

no image

プロセスの起動を確認するプログラム

プロセスが起動しているかを確認するプログラムを Java で書いてみました。Excel のプロセス確

記事を読む

no image

ディレクトリに関するユーティリティ

ディレクトリに関するスニペットをいくつか書いた。いつかコピペする日が来ると思うのでメモしておく。

記事を読む

no image

Java から VBScript を使って Excel を印刷する

背景 Java のデスクトップアプリを作成していたときの要件に「Excel で作成された帳票を印刷

記事を読む

no image

Functions#compose() を使って Function を合成するサンプル(Java8 との比較付き)

Java8 と GoogleGuava の Function について コードの違いを書いた。 その

記事を読む

no image

Stream#map()とStream#collect()を使ってListを生成する

Java8 から導入された Stream API も少しずつ慣れてきて、「そういえばこういうパターン

記事を読む

icatch-3361b5e1-resized

Optional型の変数にget()とifPresent()は使わない

Java8 から導入された Optional を勉強するため、過去にプライベートで書いたコードに O

記事を読む

icatch-upload_1229138273_mini-thumbnail

InputStream に格納されているストリームデータのサイズを取得する

Jersey を使った Web アプリを作成中なんですが、 enctype="multipart/f

記事を読む

no image

Spark を使って JSON を返すシンプルな API を書いてみた

必要に迫られてモックの API を作成することになった。 大した工数を割けないので使ったことのある

記事を読む

medium_182531101

ClassLoader を使って getResourceAsStream で取得したファイルを UTF-8 で読み込む

よく使う割には覚えられず毎回調べている気がするので備忘録としてメモしておきます。 文字コードを指定し

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


− 六 = 1

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑