- PR -

JSPを使ってFileをDownloadするには?

投稿者投稿内容
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-06-25 23:28
下記のように改行等を消し、JSPコンパイル時にHTMLとして解釈されるコードがないように
するとIllegalStateExceptionが発生しなくなりました。
つまり、response.getOutputStreamを2回呼び出すことではなく、2回目の
response.getOutputStreamより前にout.print等の出力系メソッドが呼び出されるのが
問題だったのです。
これで何の問題もなく、JSPでバイナリファイルのダウンロードが行えます。
※[EOF]はファイルの終端を表します。
コード:

<%@ page contentType="application/octet-stream" import="java.io.*,javax.servlet.*" %><%
String data_path = "C:\\java\\Tomcat4.0\\webapps\\asip\\";
String data_name = "aa.bb";

response.setHeader("Content-Disposition","attachment; filename="+data_name);
response.setHeader("Content-Description","file download test");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(data_path + data_name));

ServletOutputStream out2 = response.getOutputStream();

int x;
while((x=in.read()) >= 0){
out2.write(x);
}
in.close();
out2.flush();
out2.close();
%>[EOF]



[ メッセージ編集済み 編集者: asip 編集日時 2002-06-25 23:49 ]
しょむ
ぬし
会議室デビュー日: 2001/09/06
投稿数: 430
投稿日時: 2002-06-26 00:37
あ〜、まぁ、めくじらたててるわけじゃないんですけどね:)
Javaを使う意味や利点のひとつをつぶすのもどうかなと。

で、JSP の話ですが、たしかにちーとも先に出力してなければだいじょぶ「そう」ではありますが、規格として保証されてるわけではないんではないかとも思ったり。
たまたま、Tomcat4 の実装がそうなってくれただけで。
まぁ、今動けばよければそれでもいいんですけど。

んで、そこまでやるんなら、すなおに Servlet 使えばいいじゃんと思うわけですわ。
変なところに気を回してまで JSP にするメリットがあるとも思えんです:)
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-06-26 01:19
引用:

しょむさんの書き込み (2002-06-26 00:37) より:
あ〜、まぁ、めくじらたててるわけじゃないんですけどね:)
Javaを使う意味や利点のひとつをつぶすのもどうかなと。

で、JSP の話ですが、たしかにちーとも先に出力してなければだいじょぶ「そう」ではありますが、規格として保証されてるわけではないんではないかとも思ったり。
たまたま、Tomcat4 の実装がそうなってくれただけで。
まぁ、今動けばよければそれでもいいんですけど。

んで、そこまでやるんなら、すなおに Servlet 使えばいいじゃんと思うわけですわ。
変なところに気を回してまで JSP にするメリットがあるとも思えんです:)



「できる」と「できない」の差は大きいと思います。JSPでもServletでもどちらでもでき
るという前提で、Servletを使うかJSPを使うかは開発サイドの裁量です。

 JSPはJSPコンパイラによってServletのソースコードへと変換されてからバイトコードへ
とコンパイルされているわけですから、Servletにしたとしても今回のJSPで起こったよう
な問題は起こりえます。

JSPの規格云々を言い出せば、現在稼働しているシステムで利用されているJSPファイルが
将来動かなくなる可能性はあります。今回のJSPが特別なわけではありません。
Servletについても同様です。
YOU@IT
ぬし
会議室デビュー日: 2002/03/29
投稿数: 284
お住まい・勤務地: 大阪
投稿日時: 2002-06-26 09:17
>「java.lang.IllegalStateException: このレスポンスに対してgetOutputStream()はすで
>に呼び出されています」という例外がログに吐かれますが、警告みたいなもので、動作
>上、特に問題はないように思います。

警告と言うよりもしっかり例外がスローされてますよ。
これはしょむさんもおっしゃっているように、たまたま結果が希望どおりになった
だけで、常にその結果が得られる保証はないですし、そのWebアプリケーションの
ポータビリティ性も疑問でしょうね。

>動作に支障なくても、それはたまたまでは。
>例外を吐きながら動くものなんて論外かと。

そうですね、やはりServletResponseからは、
「WriterかStreamかどちらか一方を1回だけ取得できる」
と考えるのが適切かと思います。

となるとこの場合はJSPよりServlet・・・と言うかJSPを使う理由も
特に無いように思います。
Paul
ベテラン
会議室デビュー日: 2002/04/30
投稿数: 75
お住まい・勤務地: 東京
投稿日時: 2002-06-26 09:33
> ServletOutputStream out2 = response.getOutputStream();
は冗長です。
JSPWriterでwrite(int c)を使えば、それでいいのです。
_________________
Paul K.Nakagome
YOU@IT
ぬし
会議室デビュー日: 2002/03/29
投稿数: 284
お住まい・勤務地: 大阪
投稿日時: 2002-06-26 09:34

>JSPはJSPコンパイラによってServletのソースコードへと変換されてからバイトコードへ
>とコンパイルされているわけですから、Servletにしたとしても今回のJSPで起こったよう
>な問題は起こりえます。

起こらないと思います。Servletであればプログラマが(ほぼ)完全にHttpServletResponse
オブジェクトを制御できますから・・・JSPではコンテナがServletに変換する際にどのような
コードを吐くかは実装依存ですから完全に把握できないですよね。
そう言う意味ではこういうロジックはServletに実装すべきだと思います。

>JSPの規格云々を言い出せば、現在稼働しているシステムで利用されているJSPファイルが
>将来動かなくなる可能性はあります。今回のJSPが特別なわけではありません。
>Servletについても同様です。

それを言い出すとキリがないのでは・・・(^^;

ちなみに先ほどの書き込みで自分で「JSPを使う理由は特にない」と書きましたが、
唯一あるとすれば、バージョンアップの再に再ビルドせずにJSPファイルを更新する
だけで済む、と言う事でしょうか・・・
# これにしてもあまりオートリロードを信頼するのはどうかと思いますが。

そもそもJSPはServletでプレゼンテーションロジック(HTMLをprintしまくるとか)を記述する
のを避けるためと、WebデザイナがServletのJavaコードを修正するのが困難である、と言う
理由から策定された物だと認識しています。
しかし、今回のコードを見るとJSP中に記述されているのはまさに”Javaコードだけ”ですよね。
それなら素直にServletに書く方が良いのでは?と思いますね。
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-06-26 10:51
引用:

YOU@ITさんの書き込み (2002-06-26 09:34) より:

>JSPはJSPコンパイラによってServletのソースコードへと変換されてからバイトコードへ
>とコンパイルされているわけですから、Servletにしたとしても今回のJSPで起こったよう
>な問題は起こりえます。

起こらないと思います。Servletであればプログラマが(ほぼ)完全にHttpServletResponse
オブジェクトを制御できますから・・・


ダウンロード失敗時やダウンロード事前処理失敗時にエラー画面への遷移が必要な場合に
おいてServletのロジックの記述如何によっては起こる可能性があると思うのですが??
※「今回のJSPで起こったような問題」とは「IllegalStateExceptionが発生する」です。


[ メッセージ編集済み 編集者: asip 編集日時 2002-06-26 11:01 ]
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-06-26 11:18
引用:

YOU@ITさんの書き込み (2002-06-26 09:34) より:
(省略)
JSPではコンテナがServletに変換する際にどのような
コードを吐くかは実装依存ですから完全に把握できないですよね。
そう言う意味ではこういうロジックはServletに実装すべきだと思います。
(省略)
しかし、今回のコードを見るとJSP中に記述されているのはまさに”Javaコードだけ”ですよね。
それなら素直にServletに書く方が良いのでは?と思いますね。



以前も書きましたが、「JSPでファイルダウンロード」という手法を推奨しているわけ
ではありません。
 単純に「JSPでもできますよ」といっているだけです。この手法の通用しないサーブレット
コンテナではこの手法は使えないというだけです。
Servletで実装するかJSPで実装するかは個々のシステムの開発サイドの裁量です。

[ メッセージ編集済み 編集者: asip 編集日時 2002-06-26 11:24 ]

スキルアップ/キャリアアップ(JOB@IT)