- ソースコードID: 473
- 登録日時: 2008/03/17 21:12
- 最終更新日時: 2008/10/22 20:30
- アクセス数: 7143
- タグ: java ファイル ダウンロード content-disposition attachment servlet
説明
サーバにあるファイルをクライアント(ブラウザ)にダウンロードするメソッドです。"Content-Disposition:
※クライアントから、ダウンロード要求があった場合にサーバ側で行う処理です。
【変更履歴】
2008.03.19
コメント

- 2:台北猫々
- 2008/03/18 18:52
う~ん。例外処理はノウハウとして欲しいところですよね~(ちょっと、はしょっちゃいました(^^;)
ところで、アップしているソースで考慮すべき例外としては、
・IOException
・FileNotFoundException
の2つですよね?(異常系の組み方によっては、IllegalStateExceptionが発生するかなと思いますが)
・SocketException
は、IOExceptionにマッピングされてしまうのでは?
それと、
----NGCode
while((len=in.read(buf))
}
----NGCode
という判定方法については問題無いような気がするのですが、具体的にどのようにNGなのかご教示いただけませんか?

- 3:ゲスト (1です。)
- 2008/03/19 16:39
回答のみ
>
>
拾い方によりけりです。
FileのIO例外とResponseのSocket例外は両方共にIOExceptionで拾えますが、ユーザがダウンロードの途中キャンセル等を拾うケースではSocket例外で拾うほうが正確になります。
ユーザキャンセル等は例外をキャッチはしてもプログラムとしての異常には落とすと変ですよね?
----NGCode
while((len=in.read(buf))
}
----NGCode
に関しては誤記です。
失礼いたしました。「動作」としては正常に動くけど「論理的」な意味合いでのNGでしかないですね^^;
----NGCode
while((len=in.read(buf))
}
----NGCode
としたつもりが[0]が[-1]のままになってしまいました。
>
の部分で、0の場合まだデータが残っていることを示すため、、、のつもりだったのですが、誤記してしまいました。

- 4:台北猫々
- 2008/03/19 22:54
>ユーザがダウンロードの途中キャンセル等を拾うケースではSocket
>例外で拾うほうが正確になります。
なるほどです。
##############################
#↓以下は、この記事の読み手に、ダウンロードのクライアントユ
#ーザのキャンセルをサーバ側で「常に」検知できるという誤解を
#与えないために書いています。
##############################
ただ、サーバ→ブラウザのダウンロード処理は、ダウンロードダイアログ表示のバックグラウンドで行われているため、ユーザキャンセルをいつもSocket例外で拾えるわけではないという、条件付きですね。
(例えば、サイズの小さいファイルでは、ダイアログが表示される時には、ダウンロード処理は完了し、サーブレットは終了してしまっており、SocketExceptionも発生しない)。
##############################
>失礼いたしました。「動作」としては正常に動くけど「論理的」
>な意味合いでのNGでしかないですね^^;
なんとなく、そんな気もしていたのですが、念のためお聞きしてしまいました(^^)

- 5:ゲスト (1です。)
- 2008/03/23 04:17
蛇足なんだろうなというのはイヤというほど解かっていますし、しつこくて申し訳ないですが、乗りかかった船なのでついでです。
ノウハウに補足します。
>
の[1024]はパフォーマンスを見たものです。
よく知られてるチューニングだと、サーバ上のファイルIOに時間がかかる場合(Webサーバとは別のハードのファイルにアクセスする等)これはwhileの周期よりバッファ読み込みが遅くなるケースです。このチューニングは主にバッファの読み込みサイズとwhile文を遅延させることで行います。
以下のメソッドを確認すると、
http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/ja...(byte[],%20int,%20int)
----抜粋
できるだけ多くのバイト数を読み込もうとします。
----終了
とあるため、そのときの「できるだけ」が0byteである場合無駄にwhile文がCPU時間をとりCPUフル現象が発生します。
原因がIO時間によるのであれば、スリープをはさむことで解決します。
また、メモリ容量が少ない環境(昨今そんなことは少ないでしょうけど)では、例えば元のファイルのサイズを拾ってきてbyte配列のサイズにしてしまうと、そのファイルが大きい場合、かなり無駄なメモリ空間を取ってしまうというケースも過去に見たことがあります。(私が見たケースは極端で1.5Gのファイルでした。そんなファイルのダウンロードなんてWebでしないで欲しいものですが。。。)なので、固定サイズで発行してあることそのものにも意味があります。

- 6:ゲスト (ヒロ)
- 2008/10/22 19:50
attachment部分をinlineに変更して、ファイルをダウンロードし別ウィンドウで開くようにしましたが、ウィンドウが元ウィンドウの裏側に表示されてしまうことがあります。
ダウンロードして、開くウィンドウが常に最上位になるようにするには、どうすれば良いでしょうか?
ちなみに、ダウンロードするファイルはPDFで、AcrobatReaderにて開いています。

- 7:台北猫々
- 2008/10/22 20:30
JavaScriptでwindow.openして子ウインドウを開いて、その子ウインドウ内でPDFファイルを開くということですか?
親ウインドウから、(子ウインドウのハンドル).focus()して強制的に最前面にしても駄目ということでしょうか?
前へ 1 次へ![]()
コメントする
[block]から[/block]までの範囲はブロック表示されます。
部分的に目立たせたい時や、引用などにお使いください。
[code]から[/code]までの範囲は等幅表示されます。
ソースコードや設定ファイルの記述などにお使いください。


















Javaのダウンロード処理を書くのであれば、以下の説明も欲しいかな。。。
out.write(buf,0,len); > -1){
out.write(buf,0,len);
発生する例外種別として、
・IOException
・FileNotFoundException
・SocketException
などなど、、、色々ありますよね?
また、よく見るケースとしては、
----抜粋開始
while((len=in.read(buf))!=-1){
}
----抜粋終了
の部分が
----NGCode
while((len=in.read(buf))
}
----NGCode
となっていたりするケースも見られます。
とか、、、ノウハウならそこまで欲しいかも