java.lang.IllegalStateException: getOutputStream() has already been called for this response
Solution 1
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.
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
.
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";
}
Solution 2
Remove all space and linebreaks between closing %> and opening <% and use <%@page trimDirectiveWhitespaces="true" %> at top can solve this issue.
Solution 3
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.
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.
Solution 4
You need to have a inputSteam
set for the inputName
paramater but I cannot see it anywhere in your code.
You can set up a ByteArrayOutputStream
and store the data to ByteArrayInputStream
like below
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.
Akhilesh N
Updated on June 05, 2022Comments
-
Akhilesh N almost 2 years
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:<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.How to avoid this?
-
Akhilesh N over 11 yearsI created the Streams with inputStream as excelStream now i am getting this error java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [excelStream] in the invocation stack. Check the tag specified for this action. My Struts XML is same as above.
-
Quincy over 11 yearsYou need to have a getter method
getExcelstream()
in your action class and returns the inputStream in it. -
Rndm over 10 yearsI do not have the issues mentioned in this answer but getting the same exception when downloading large files.
-
Rndm over 10 yearsCorrect, but I have written the correct syntax and still get the same exception.
-
Roman C over 10 years@Rndm There's also error in the header for content disposition, the server is not able to handle such filenames. And why don't you use the
stream
result? -
Andrea Ligios over 10 yearsIf the only common thing is the Exception, you should open a question of your and put the bounty on that