Java.lang.IllegalStateException: getOutputStream () has already been called for this response
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
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";
Mine 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 just give a button that opens me an open save dialog. After clicking this button, I am getting an exception.
How can you avoid this?
source to share
It's just a syntax error, the server is confused about how to handle this type of content
<param name="contentType">"application/vnd.ms-excel"</param>
change to
<param name="contentType">application/vnd.ms-excel</param>
note, the value param
is a string without double quotes.
So the actual 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 must initialize excelstream
and provide the getter before returning the result. workbook
do not write in the answer, let it write in 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";
}
source to share
Remove absolutely all spaces and gaps between closing%> and opening <%. With space in between, you can automatically call getOutputStream (). Since those spaces or lines are split into the output in the browser: it calls getOutputStream () to render.
This is the only way to find this error in JSP. Otherwise, you will have to rewrite the code that returns the binary as a servlet and just use the JSP page as the launch page to send the user to the servlet when the button is clicked.
source to share
The parameter inputName
needs to be set inputSteam
, but I don't see it anywhere in your code.
You can customize ByteArrayOutputStream
and save the data to ByteArrayInputStream
as shown below
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
/** code to write to outputsteam ***/
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
And you don't need to include these codes
response.setContentType("application/vnd.ms-excel");
outStream= response.getOutputStream();
response.setHeader("Content-Disposition", "attachment; filename=/timesheet.xls");
since you can set the whole thing as a result of the strut action.
source to share