I am using Apache POI for generating Excel file in Java Servlets.
getExcel() function returns HSSFWorkbook, which I want to send to the client.
HSSFWorkbook wb = getExcel();
This is what I have tried so far.
//block1
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);
byte [] outArray = outByteStream.toByteArray();
response.setContentType("application/ms-excel");
response.setContentLength(outArray.length);
response.setHeader("Expires:", "0");
response.setHeader("Content-Disposition", "attachment; filename=Demo1.xls");
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();
//block2
request.setAttribute("Message", str1);
request.setAttribute("MessageDetails", str2);
request.getRequestDispatcher("/MyFile.jsp").forward(request, response);
Above code sends excel file to the client, but gives me exception:
java.lang.IllegalStateException: Cannot forward after response has been committed
If I remove the block1 or block2 from above code then it will not give error, but I want to send client Excel file and two attributes which I have added to request object.
So can send Excel file to client using request.getRequestDispatcher ? Or is there any better way for doing this?
Any suggestion will be appreciated.
Edit1
I know why I am getting the IllegalStateException, but then my question is how should I send ExcelFile and Request Attributes both to the client?
Edit2
The Reason why I want to send both Excel file and Attributes to the client is that MyFile.jsp has a
${Message}
Edit3
The Reason why I want to send message to client is that I am sending this Excel file as an response to Import Excel operation in which client will provide excel file for inserting data in database, and then I am highlighting the excel rows which cannot be inserted due to duplication or any other reasons. So I want to show Import statistics in the Message to client and give him copy of excel file with error rows highlighted.
解决方案
You are flushing your response and then trying to forward. Container has already sent the response back to the client and now is in a dilemma as to how to forward the request to another JSP, hence it aborts the operation mid way throwing an Exception. HTTP is a request-response model . Once you request , you get back a response . But once the response is already committed the whole transaction is over.
outStream.write(outArray);
// you already committed the response here by flushing the output stream
outStream.flush();
//block2
request.setAttribute("Message", str1);
request.setAttribute("MessageDetails", str2);
// this is illegal after you have already flushed the response
request.getRequestDispatcher("/MyFile.jsp").forward(request, response);
As per the Javadoc:
IllegalStateException - if the response was already committed.
After EDIT1:
No you cannot do both . You need to decide what you want. Write the bytes to the response setting proper HEADERS and MIME-TYPE. You cannot get the browser download something as well as show a JSP page from the same response.