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
java.lang.IllegalStateException: getOutputStream() has already been called for this response
提问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.xml
looks 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 param
value 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 excelstream
and provide getter before returning result. The workbook
shouldn'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
You need to have a inputSteam
set for the inputName
paramater but I cannot see it anywhere in your code.
您需要inputSteam
为inputName
参数设置一组, 但我在您的代码中的任何地方都看不到它。
You can set up a ByteArrayOutputStream
and store the data to ByteArrayInputStream
like 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 中设置所有这些。