At IEC, we have an application used to report inventory counts. Part of the app creates an Excel spreadsheet using POI. The user selects a batch from a select/combo, click on the button, and the server sends them a spreadsheet. The basic work flow is this:
Display the page
User selects a batch and clicks the button
JSF calls the specified action on the backing
The backing bean creates the spreadsheet, then navigates to success.jsp, a plain ol' JSP
The JSP pulls the backing bean from the session, gets the workbook reference from it, and streams that to the user using a ServletOutputStream.
This works well under Tomcat and JSF 1.1. Our goal, though, is to migrate to a full JEE 5 environment, hosted on Glassfish. Glassfish, though, ships with JSF 1.2, as JSF is now part of the JEE spec (starting with version 5). This poses a problem, though, as there has apparently been a good deal of work in view handling in 1.2 that breaks this behavior. Ed Burns has been nice enough to take a look for me, but, while waiting for him to get time to help me, I took a stab at fixing it. My tentative work around for it is as follows:
Alter the form to use a "normal" (read as: non-JSF) form and submit to a servlet.
Write a servlet that in effect duplicates the JSF lifecycle:
Build/load the FacesContext
Get a reference to the backing bean
Pull the batch id from the request and set it on the backing bean.
Call the action method.
At this point, the servlet works the same as the JSP:
Get the reference to the workbook
Stream the workbook to the user.
This works, but is a pretty ugly hack. In fact, check out the code: