2

これが私のコードで、次の例外が発生しています

HTTP Status 500 - Unable to show problem report: java.lang.IllegalStateException: getOutputStream() has already been called for this response

コード:

WorkbookSettings wbSettings = new WorkbookSettings();    
OutputStream outStream = null;
            
try
{               
  wbSettings.setLocale(new Locale("en", "EN"));             
  response.setContentType("application/vnd.ms-excel");                  
  outStream= response.getOutputStream();                
  response.setHeader("Content-Disposition", "attachment; filename=/timesheet.xls");             
  WritableWorkbook workbook = Workbook.createWorkbook(outStream, wbSettings);              
  workbook.createSheet("Report", 0);               
  WritableSheet excelSheet = workbook.getSheet(0);              
  service.createLabel(excelSheet);              
  service.createContent(excelSheet);                    
  workbook.write();             
  workbook.close();             
  outStream.flush();               
  outStream.close();                
}               
catch(Exception e)
{
}           
finally
{               
  //outStream.close();      
}   
return "generateReport";

Struts.xmlはこのように見えます:

<result type="stream" name="generateReport">                   
 <param name="contentType">"application/vnd.ms-excel"</param>                  
 <param name="inputName">excelstream</param>                  
 <param name="contentDisposition">contentDisposition</param>                   
 <param name="bufferSize">1024</param>              
</result>

open, saveJSPでは、ダイアログボックスを表示するボタンを提供しているだけです。そのボタンをクリックすると、例外が発生します。

これを回避する方法は?

4

4 に答える 4

2

これは単なる構文エラーです。サーバーはそのようなコンテンツ タイプの処理方法を混乱させています。

<param name="contentType">"application/vnd.ms-excel"</param>

への変更

<param name="contentType">application/vnd.ms-excel</param>

param値は二重引用符のない文字列であることに注意してください。

したがって、有効な結果は次のようになります。

<result type="stream" name="generateReport">
  <param name="contentType">application/vnd.ms-excel</param>
  <param name="contentDisposition">attachment;filename="timesheet.xls"</param>
  <param name="inputName">excelstream</param>
</result>

アクション コードは、excelstream結果を返す前に を初期化し、getter を提供する必要があります。はworkbook応答に書き込むべきではなく、 に書き込むようにしByteArrayOutputStreamます。

private InputStream excelstream;

public InputStream getExcelstream() {
  return excelstream;
}  

public String execute() throws Exception {
  WorkbookSettings wbSettings = new WorkbookSettings();

  try  {  
    ByteArrayOutputStream outstream = new ByteArrayOutputStream();  
    wbSettings.setLocale(new Locale("en", "EN"));        
    WritableWorkbook workbook = Workbook.createWorkbook(outstream, wbSettings);   
    workbook.createSheet("Report", 0);    
    WritableSheet excelSheet = workbook.getSheet(0);    
    service.createLabel(excelSheet);    
    service.createContent(excelSheet);          
    workbook.write();    
    workbook.close();  
    excelstream = new ByteArrayInputStream(outstream.toByteArray());        
  } catch(Exception e) {    
    e.printStackTrace();
    throw e;
  }

  return "generateReport";
}
于 2013-09-05T10:50:04.433 に答える
2

%> を閉じてから <% を開くまでのすべてのスペースと改行を完全に削除します。それらの間にスペースがあると、 getOutputStream() が自動的に呼び出される可能性があります。これらのスペースまたは改行はブラウザへの出力として扱われるため、getOutputStream() を呼び出してレンダリングします。

JSPでこのエラーを解決する唯一の方法です。それ以外の場合は、バイナリ ファイルを返すコードを書き直してサーブレットにし、JSP ページを起動ページとして使用して、ユーザーがボタンをクリックしたときにユーザーをサーブレットに送信する必要があります。

于 2013-09-06T22:57:34.720 に答える
1

これ読んだことがありますか?

inputSteamパラメータのセット が必要ですがinputName、コードのどこにも表示されません。

以下のようByteArrayOutputStreamにデータを設定して保存できますByteArrayInputStream

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

/** code to write to outputsteam ***/

ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());

そして、これらのコードを含める必要はありません

response.setContentType("application/vnd.ms-excel");    

outStream= response.getOutputStream();

response.setHeader("Content-Disposition", "attachment; filename=/timesheet.xls");

ストラットアクションの結果でこれらすべてを設定できるためです。

于 2012-12-28T06:47:48.163 に答える