- PR -

ダウンロードダイアログの表示について

1
投稿者投稿内容
trick
常連さん
会議室デビュー日: 2003/11/14
投稿数: 31
投稿日時: 2007-01-20 03:14
trickと申します。

サーバ側で作成したExcelファイルを、クライアント側にダウンロードさせるPGを作成
しています。
Eclipseで作成していますが、URLの指定がlocalhostだとダウンロードダイアログが表示
されますが、IPアドレス(別サーバ)で指定すると表示されません。
ServletOutputStreamをcloseするところまでいっているので問題ないのではないかと思っているのですが、このような現象がお分かりになる方がいましたらご教授下さい。
ちなみに、ログには以下のように出力されています。
【ログ抜粋】
2007.01.20,02:41:25,578,ApplicationDispatcher.java:704,ERROR,サーブレット jsp のServlet.service()が例外を投げました
java.lang.IllegalStateException: getOutputStream()はこのレスポンスに対して既に呼び出されています

【ソース抜粋】
private void makeExcel(HttpServletResponse response, DynaActionForm dynaForm) throws IOException {
// ファイル読み込み用バッファ
byte buffer[] = new byte[1024];
// クライアント側の文字エンコーディングのままのファイル名
String fileName1 = dynaForm.get("EXCEL_FILE").toString();
// Windows-31Jに変更されたファイル名
String fileName2 = new String(fileName1.getBytes("Windows-31J"), "ISO8859_1" );
// Excelのワークファイルパス取得
String workPath = dynaForm.getString("WORK_PATH").toString();
// contentTypeを出力
response.setContentType("application/octet-stream");
// ファイル名の送信(attachment部分をinlineに変更すればインライン表示)
response.setHeader("Content-disposition", "attachment; filename=\""+fileName2+"\"");
// ファイル内容の出力
ServletOutputStream out = response.getOutputStream();
FileInputStream fin = new FileInputStream(workPath + fileName1);
int size;
// ファイルの読み込みが成功した場合、ファイルをレスポンスに出力する。
while((size = fin.read(buffer))!=-1) {
out.write(buffer,0, size);
}
fin.close();
out.close();
}

【環境】
jdk1.5.10
Tomcat5.5
Struts1.2.9
Eclipse3.2

以上、よろしくお願いいたします。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-01-20 10:04
getOutputStream()がそのレスポンスに対して既に呼び出されているため、例外が発生しているようです。
仕様上は何度呼び出しても問題なさそうですが。
まず、例外のスタックトレースからどの行で発生しているのかを確認してみましょう。
trick
常連さん
会議室デビュー日: 2003/11/14
投稿数: 31
投稿日時: 2007-01-20 10:14
引用:

インギさんの書き込み (2007-01-20 10:04) より:
getOutputStream()がそのレスポンスに対して既に呼び出されているため、例外が発生しているようです。
仕様上は何度呼び出しても問題なさそうですが。
まず、例外のスタックトレースからどの行で発生しているのかを確認してみましょう。



ログでは、以下のように出力されています。
私には、下記では、皆目検討がつきません・・・。

2007.01.20,10:05:55,453,ApplicationDispatcher.java:704,ERROR,サーブレット jsp のServlet.service()が例外を投げました
java.lang.IllegalStateException: getOutputStream()はこのレスポンスに対して既に呼び出されています
at org.apache.catalina.connector.Response.getWriter(Response.java:599)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:195)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:111)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:124)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:117)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:174)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:115)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75)
at org.apache.jsp.jsp.Common.ExcelMaking_jsp._jspService(ExcelMaking_jsp.java:86)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:334)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
at org.apache.struts.action.RequestProcessor.doInclude(RequestProcessor.java:1116)
at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestProcessor.java:260)
at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:398)
at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(TilesRequestProcessor.java:318)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:241)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)

その後の調査で、web.xmlに以下を追加すると行ける、という情報があったので試してみました。

<param-name>module</param-name>
<param-value>pnuts.servlet</param-value>

結果、以下のログが出力されます。

2007.01.20,10:11:40,218,RequestProcessor.java:528,WARN,処理できない例外がスローされました: class org.apache.catalina.connector.ClientAbortException
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-01-20 11:11
仕様書やAPIドキュメントに書いてありますが、getOutputSream を呼び出した後に getWriter を呼び出してはいけません。
makeExcel メソッドは JSP ではなく、サーブレットから呼び出すようにしましょう。
trick
常連さん
会議室デビュー日: 2003/11/14
投稿数: 31
投稿日時: 2007-01-20 11:16
引用:

インギさんの書き込み (2007-01-20 11:11) より:
仕様書やAPIドキュメントに書いてありますが、getOutputSream を呼び出した後に getWriter を呼び出してはいけません。
makeExcel メソッドは JSP ではなく、サーブレットから呼び出すようにしましょう。



ご回答ありがとうございます。
実は、サーブレットから呼び出しています。
画面上に、「作成中です」の画面をモーダルで出した後にレスポンスを出力しようとしていたのがまずかったようです。
親切にご回答いただきありがとうございました。
別の方法を検討します。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-01-20 11:19
>実は、サーブレットから呼び出しています。
スタックトレースをみると JSP 内で発生しているように見えますが、別件のスタックトレースなのでしょうか・・・?

いずれにせよ、例外が発生したときは例外のメッセージ、例外の種類、例外の発生箇所を確認して原因を考えるクセをつけるといいですよ!
trick
常連さん
会議室デビュー日: 2003/11/14
投稿数: 31
投稿日時: 2007-01-20 11:46
引用:

インギさんの書き込み (2007-01-20 11:19) より:
>実は、サーブレットから呼び出しています。
スタックトレースをみると JSP 内で発生しているように見えますが、別件のスタックトレースなのでしょうか・・・?

いずれにせよ、例外が発生したときは例外のメッセージ、例外の種類、例外の発生箇所を確認して原因を考えるクセをつけるといいですよ!



面目ない・・・。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-01-20 11:59
>面目ない・・・。
いえいえ。
慣れないと例外発生時にずらずらと表示されるスタックトレースはかなりドッキリして目を背けたくなりますよね。
でも例外メッセージ、例外の型、スタックトレースは事の原因を実に雄弁に物語っています。
#そういえば例外/エラーの読み方を示した参考書ってあまりないかもしれませんね?

いっぱいエラー・例外を発生させて実力アップしてください!

1

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