- - PR -
Struts Actionクラスでのダウンロード
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-09-09 11:10
はじめまして。
WEB開発の案件で、DBから取得したデータをCSV,XMLでのダウンロードを行う。というものがあるのですが、ちょっとわからない動作をするので何か情報をお持ちの方がいらっしゃいましたらご教授願いたいです。 動作として ・抽出したデータをStringに変換、それをresponseのバッファに格納する ・アクションクラスにてダウンロード用のメソッドを呼び出す。 ・メソッドが呼ばれた後アクションクラスでフラッシュし、フォワードはnullを返す。 現象として ・2kぐらいのデータならCSV,XMLでダウンロードできる。(ダウンロードダイアログにてダウンロード可能) ・30kぐらいのデータの場合、ダウンロードできない。(ダウンロードダイアログは表示しますが、ダウンロードを行うときに「このインターネットのサイトを開くことが・・・」のメッセージが表示されます) 今まで行ったこと ・response.setBufferSize()でダウンロードファイル分のサイズを指定 ・レスポンスヘッダにもダウンロードファイル分のバッファのサイズを指定 ・ヘッダでキャッシュを使用するように変更 ・ヘッダのコンテントタイプをそれぞれ指定(text/csv,text/xml) なにをやっても結果は一緒でした。 何か見落としている部分でもあるのでしょうか?申し訳ありませんがよろしくお願いします。 環境は以下のとおりです IE6.0 SP2 WindowsXP Professional SP2 J2SE 1.4.2_07 J2EE 1.3.1 Apach 以下にソースコードを抜粋しました。 //下記はアクションクラスでダウンロードを呼び出す部分です writeToStream("CSV", output, "test", response); response.getOutputStream().flush(); response.getOutputStream().close(); return null; //ダウンロードメソッド void writeToStream(String format, String output, String fileName, HttpServletResponse response) { try { String fileNameExt = ""; if("CSV".equals(format)) { fileNameExt = ".csv"; } else if("XML".equals(format)) { fileNameExt = ".xml"; } response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + fileNameExt + "\""); response.setHeader("Cache-Control", "no-cache"); if(output != null) { OutputStream os = response.getOutputStream(); OutputStreamWriter w = new OutputStreamWriter(os); BufferedWriter writer = new BufferedWriter(w); writer.write(output); writer.close(); w.close(); } } catch(Exception e){} } | ||||||||||||
|
投稿日時: 2005-09-09 11:22
>catch(Exception e){}
これで何か例外が握りつぶされているってことはないでしょうか? 例外をキャッチしたら常に適切なフォローをいれるか、最低限スタックトレースを出力するようにしましょう。 | ||||||||||||
|
投稿日時: 2005-09-09 11:35
さらにいうと、
この部分は
でいいのではないですか? それからレスポンスの出力ストリームに対するフラッシュや クローズは、原則としてサーブレット内で行うものではないです。 | ||||||||||||
|
投稿日時: 2005-09-09 11:36
インギ様 返答ありがとうございます。説明不足で申し訳ないです^^; 例外に関してはログ出力専用のクラスで管理を行っています。 ここでは例外をスローしている様子が見られないため困ってます(ToT) 以下修正 catch(Exception e) { //ログ出力を行うクラスを使用し、例外を出力 log.debug("An exception occurred ProcessOrderDownload ", e); } | ||||||||||||
|
投稿日時: 2005-09-09 11:43
uk様 返答ありがとうございます。 フォワードにnullを返しているのでフラッシュやクローズを行わないといけないのかな?と思い記述したものです^^; 早速上記のことを試してみたいと思います。 ありがとうございます | ||||||||||||
|
投稿日時: 2005-09-09 12:21
uk様から指摘を受けた部分を参考に修正を行い確認しましたが、現象は変わりませんでした。。。
uk様ありがとうございました。解決できなくて申し訳ないです(ToT) こちらでももう少し調べてみますが、みなさんのご助力よろしくお願いします。 | ||||||||||||
|
投稿日時: 2005-09-09 16:05
途中経過ですが、現状報告まで。
レスポンスヘッダのContent-Dispositionにinline;を指定して実行しました。 データ件数が少なければダイアログが表示される(ファイルの拡張子は.csv)のですが、データ件数が多いと画面にデータを表示してしまいます(ファイルの拡張子がない)。 データ件数の大小に関わらずダイアログを表示し、CSV(もしくはXML)としてダウンロードさせたいです。 よろしくお願いします | ||||||||||||
|
投稿日時: 2005-09-09 22:42
私も似たような現象になったことがあります。
http://support.microsoft.com/default.aspx?scid=kb;ja;896219 web等で調査した結果、私の環境では以下のようにすることで 正常ダウンロードができるようになりました。 response.setContentType("application/octet-stream;charset=Windows-31J"); response.setHeader("Pragma", ""); response.setHeader("Cache-Control", ""); response.setHeader("Content-Disposition", "attachment; filename=xxx.csv"); 参考になれば幸いです。 |