Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

Struts上からローカルへのダウンロードと、ダウンロード後のリフレッシュについて

いつもお世話になっております。
ご教授頂きたく書き込みをさせて頂きます。

画面上でボタン押下時に、画面に出ている情報をEXCELファイルとして出力し、出力後に画面をリフレッシュするという機能があります。
これを以下のようなinActionで実施しています。

 public ActionForward excelDownload(ActionMapping mapping, ActionForm form
  , HttpServletRequest request, HttpServletResponse response){
  
  1.画面の情報を取得する
  2.取得した情報からEXCELファイルを作成する(wbHssfが作成されたEXCELファイルです)
  
  // 作成したEXCELを出力
  FileOutputStream fileOutHssf = new FileOutputStream(this.outputFileName);
  wbHssf.write(fileOutHssf);
  fileOutHssf.close();

  // メッセージ情報生成
  ActionMessages msgs = new ActionMessages();
  msgs.add("comment_01", new ActionMessage("msg.Free","正常終了"));
  saveMessages(request, msgs);

  return mapping.findForward("success");
 }

上記のロジックでは正常に「this.outputFileName」に設定されているフォルダにEXCELファイルが出力されます。
このロジックを変更して任意のローカルフォルダにファイルをダウンロードできるようにしたいのですがうまくいきません。
試したのは以下のロジックです。

 public ActionForward excelDownload(ActionMapping mapping, ActionForm form
  , HttpServletRequest request, HttpServletResponse response){
  
  1.画面の情報を取得する
  2.取得した情報からEXCELファイルを作成する(wbHssfが作成されたEXCELファイルです)
  
  // 作成したEXCELを出力
  response.setContentType("application/octet-stream; charset=Windows-31J");
  response.setHeader("Content-Disposition","attachment; filename=\"testExcel.xls\"");
  ServletOutputStream fileOutHssf = response.getOutputStream();
  wbHssf.write(fileOutHssf);
  fileOutHssf.close();

  // メッセージ情報生成
  ActionMessages msgs = new ActionMessages();
  msgs.add("comment_01", new ActionMessage("msg.Free","正常終了"));
  saveMessages(request, msgs);

  return mapping.findForward("success");
 }

上記のロジックでダウンロード用のダイアログをポップアップさせ、ダウンロード自体は正常に行われるのですが、inActionのreturn時に以下のエラーが出力されます。

java.lang.IllegalStateException: getOutputStream()はこのレスポンスに対して既に呼び出されています

returnをnullにすればとりあえずエラーは出ず、ダウンロードも出来るのですが、それですと処理終了後の画面リフレッシュが出来ません。
どうにかしようとネット等で調べているのですが、解決に役立ちそうなサイトが発見できず困っています。
お知恵を貸して頂けないでしょうか?

6

回答

18225

閲覧

6件の回答

評価

0

画面遷移しちゃってから、JavaScriptでダウンロードさせるしかないかなぁ。

あるいは、JavaScriptで、新しいウィンドウとして開いてDLさせてから、画面遷移するか。

multipart/mixedって手もあるけど、昔やろうとしたら、IEが対応してなかった。
今は対応してるのかは不明。

評価

0

あまり内容読んでないけど。
見えないフレームでダウンロードしたら。

評価

0

返答有り難うございます。

結局ServletOutputStream fileOutHssf = response.getOutputStream();でダウンロードダイアログを開いてしまうと、OutputStreamが動いてしまい、inActionからForwardはできなくなるようですね。

回避策としてjavascript上でダウンロードダイアログを作成し、選択したフォルダパスをinActionに渡し、FileOutputStreamでファイルをダウンロードさせようと思っているのですが、javascriptでローカルのフォルダパスを取得することは可能なのでしょうか?

評価

0

度々すみません。
javascritpのみでダウンロードダイアログを出す方法はなさそうでしたので、更に回避案として以下の方法を取り作成をしました。

1.ダウンロードボタン押下時にダウンロード情報作成処理を行い、結果の情報を生成し、画面をリフレッシュする
(ダウンロードファイルはセッションに保持)
2.リフレッシュ時にダウンロード処理フラグをjspに渡す
3.ダウンロード処理フラグがある場合は連動してダウンロード処理を行う
(ServletOutputStreamでダイアログ表示、inActionの最後はreturn nullとしてダイアログ表示後処理を終了する)

順番は前後しますが、これで一応意図した動きにはなります。
(本来はダウンロード処理が完了してから画面をリフレッシュしたかったのですが・・・)

この仕様で、ダウンロードするファイルが複数になった場合はzipで圧縮して対応する予定なのですが、仮にzipにしない場合、一回のダウロードダイアログの操作で複数のファイルを一括ダウンロードすることは可能なのでしょうか?

評価

0

自分で書いてることが、できるように思える?
ブラウザは可能な限り安全な方に倒して作られる
べき。
どこかのページ専用に作られたクライアントでは
ない。

評価

0

>$さん
やはりできないのですね、素直にzipに固めてダウンロードしようと思います。
ありがとうございました。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。