java.lang.IllegalStateException:已经为此响应调用了 getOutputStream()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14065561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:56:41  来源:igfitidea点击:

java.lang.IllegalStateException: getOutputStream() has already been called for this response

javajspstruts2downloadinputstream

提问by Akhilesh N

Here is my code for which I am getting the following exception

这是我的代码,我收到以下异常

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

The code:

代码:

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";

My Struts.xmllooks Like this

我的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>

In JSP, I am just giving a button which gives me open,save dialog box. After clicking that button I am getting the exception.

在 JSP 中,我只是给了一个按钮,让我打开,保存对话框。单击该按钮后,我收到异常。

How to avoid this?

如何避免这种情况?

回答by Roman C

It's just a syntax error, the server in confuse how to handle such content type

这只是一个语法错误,服务器在混淆如何处理这样的内容类型

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

change to

改成

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

note, the paramvalue is a string without double quotes.

请注意,该param值是一个没有双引号的字符串。

So, the valid result would be

所以,有效的结果将是

<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>

the action code should initialize the excelstreamand provide getter before returning result. The workbookshouldn't write to the response, let it write to the ByteArrayOutputStream.

操作代码应该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";
}

回答by developerwjk

Remove absolutely all space and linebreaks between closing %> and opening <%. Having space between those can cause getOutputStream() to be called automatically. Because those spaces or linebreaks are being treated as output to the browser: it calls getOutputStream() to render them.

绝对删除关闭 %> 和打开 <% 之间的所有空格和换行符。在它们之间留有空格会导致自动调用 getOutputStream()。因为这些空格或换行符被视为浏览器的输出:它调用 getOutputStream() 来呈现它们。

Its the only way I've found to solve this error in a JSP. Otherwise you'll have to rewrite the code that returns the binary file to be a servlet and just use the JSP page as a launch page to send the user to the servlet when they click the button.

这是我发现在 JSP 中解决此错误的唯一方法。否则,您将不得不将返回二进制文件的代码重写为 servlet,并仅使用 JSP 页面作为启动页面,以便在用户单击按钮时将用户发送到 servlet。

回答by user2894583

Remove all space and linebreaks between closing %> and opening <% and use <%@page trimDirectiveWhitespaces="true" %> at top can solve this issue.

删除关闭 %> 和打开 <% 之间的所有空格和换行符,并在顶部使用 <%@page trimDirectiveWhitespaces="true" %> 可以解决此问题。

回答by Quincy

Have you read this?

你读过这个吗?

You need to have a inputSteamset for the inputNameparamater but I cannot see it anywhere in your code.

您需要inputSteaminputName参数设置一组, 但我在您的代码中的任何地方都看不到它。

You can set up a ByteArrayOutputStreamand store the data to ByteArrayInputStreamlike below

您可以设置一个ByteArrayOutputStream存储数据ByteArrayInputStream如下

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

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

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

And you do not need to include these codes

而且您不需要包含这些代码

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

outStream= response.getOutputStream();

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

as you can set all these in the strut action result.

因为您可以在 strut action result 中设置所有这些。