[英]java.lang.IllegalStateException: getOutputStream() has already been called for this response
[英]java.lang.IllegalStateException: getOutputStream() has already been called for this response
这是我的代码,我收到以下异常
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>
在 JSP 中,我只是给了一个按钮,它可以让我open, save
对话框。 单击该按钮后,我收到异常。
如何避免这种情况?
这只是一个语法错误,服务器在混淆如何处理这样的内容类型
<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";
}
绝对删除关闭 %> 和打开 <% 之间的所有空格和换行符。 在它们之间留有空格会导致自动调用 getOutputStream()。 因为这些空格或换行符被视为浏览器的输出:它调用 getOutputStream() 来呈现它们。
这是我发现在 JSP 中解决此错误的唯一方法。 否则,您将不得不将返回二进制文件的代码重写为 servlet,并仅使用 JSP 页面作为启动页面,以便在用户单击按钮时将用户发送到 servlet。
删除关闭 %> 和打开 <% 之间的所有空格和换行符,并在顶部使用 <%@page trimDirectiveWhitespaces="true" %> 可以解决此问题。
你需要有一个inputSteam
为集inputName
paramater但我不能看到它在你的代码的任何地方。
您可以设置一个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");
因为您可以在 strut action result 中设置所有这些。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.