| |
Strutsによるファイルのダウンロード
のっけからアレですが、Strutsにはデータをダウンロードするための特別な仕組は用意されていません。
ということで、サーブレット/JSPのAPIの範囲での記述ということで、
とりわけStruts向けに何かしているというサンプルではないのですが、
アップロードと対になっているものと思うのでついでにここに載せました。
Struts 1.1で動作確認しました。
データのダウンロードの仕組は、大きく分けて2つの実装方法があります。
1つめは、サーブレット/Strutsアクションによって、
まず対象データをWebサーバのファイルシステム内に出力し、
そのファイルのURLへのリンクをブラウザに表示する方法。
2つめは、Webサーバ上に出力せず、レスポンスオブジェクトの出力ストリームに、
データを直接書き込んでしまう方法です。
1つめの方法は安定しており開発、デバッグも簡単ですが、
サーバ上に出力したファイルを定期的に削除して回る処理が必要になります。
ということでここでは2つめの方法のサンプルをご紹介します。
このサンプルにはJSPが一切出てきません。
フォームがないのでアクションフォームBeanもありません。
動作としては、.doに直接アクセスすると、
Webブラウザが「ファイルのダウンロード」ダイアログを表示するので、
ファイル名を入力するとクライアントPC上にサンプルデータが保存されます。
その際、ブラウザのウィンドウは移動しません(フォワードなどはしません)。
Strutsアクションクラス
/*
* StreamDownloadExAction
* 2004/07/05
*/
package testcl01.struts.action;
import java.io.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.*;
/**
* サンプル・データをtext/plain形式でresponseにそのまま出力し、
* Webブラウザにファイルの保存ダイアログを表示するタイプのダウンロード処理を行います。
* つまりダウンロード対象データをサーバのファイルシステム上に全く保持しません。
*/
public class StreamDownloadExAction extends Action {
/**
* リクエスト・パラメータを受け取り処理をします。
*/
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
String defaultFileName = "download.txt";
//response.setContentType("text/plain; charset=Windows-31J");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + defaultFileName);
OutputStream os = response.getOutputStream();
OutputStreamWriter w = new OutputStreamWriter(os, "SJIS");
BufferedWriter writer = new BufferedWriter(w);
writer.write("This,is,a,sample,record,data\n");
writer.write("そして,日本語の,文字列も,出力してみます。\n");
writer.write("end.\n");
writer.close();
w.close();
os.close();
return null;
//return mapping.findForward("success");
}
}
|
でそのアクションクラスです。
まず、HttpServletResponse#setContentTypeでデータのMIMEタイプを指定するのですが、
text/plainを指定すると、Operaなどのブラウザでは、
「ファイルのダウンロード」ダイアログを表示せず、
そのままデータをブラウザに表示してしまいます。
これはデータ量が驚異的に多かった場合に、ブラウザの挙動がおかしくなる可能性があります。
ということでここではapplication/octet-streamにしています。
その後のHttpServletResponse#setHeaderで「Content-Disposition」
を指定していますが、これが「ファイルのダウンロード」ダイアログを表示させるために必要な記述です。
filename=の後には、ダイアログで出力ファイルを入力する際のデフォルト値を指定します。
struts-config.xmlへの記述
<action path="/StreamDownloadEx"
type="testcl01.struts.action.StreamDownloadExAction">
<forward name="success" path="/streamdownload02.jsp" />
</action>
|
struts-config.xmlの記述は特に問題ないと思います。
空のウィンドウが開いてしまうぞ?
ダウンロード処理は正常だが、同時にブラウザが空のウィンドウやタブを開いてしまう…
この場合の原因は以下の3つが考えられます。
- a要素の「target="_blank"」を指定している。
<a href="/download/file.zip" target="_blank">ダウンロード</a>
|
- window.open() を使っている。
window.open('/download/file.zip');
|
- ダウンロード処理の応答ヘッダに「Content-Disposition: attachment」がない。
なので解決策は、前二者の使用をやめ、さらにダウンロード処理の応答ヘッダに
「Content-Disposition: attachment」を必ず含めることです。

(first uploaded 2004/07/04 last updated 2025/08/15, URANO398)
|