javajspstrutsstruts-1

Forward to JSP after call to ServletOutputStream


As near as I can tell, this falls under a "you can't do that". I'm about to re-think my solution and work around it, but I thought that asking here was worth at least a shot.

My JSP/Spring/Struts Servlet produces reports, writes them to PDF, and queues them for download, then waits for the user to request more reports. The details aren't too important. I stream the PDF to the server with the following function call:

public static void streamFileToBrowser(File docFile, HttpServletResponse response) throws Exception {
try {
    // return file to user
    // set contextType
    response.setContentType("application/pdf");
    // setting some response headers
    response.setHeader("Expires", "0");
    response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
    response.setHeader("Pragma", "public");
    response.setHeader("Content-Disposition","attachment; filename=" + docFile.getName() );

    ServletOutputStream outs = response.getOutputStream();
    byte[] outputFileBytes = util_getBytesFromFile(docFile.getAbsolutePath());
    response.setContentLength(outputFileBytes.length);
    outs.write(outputFileBytes);    // byte[]
    outs.flush();
    outs.close();
    } catch (Exception e) {
        throw e;
    }
}

That's pretty straight-forward. I use the response's ServletOutputStream object to ship my bits. It works well.

However, sometimes I trap some errors that are caused during the generation of the reports. They're informative messages like "There were no orders from account blah-blah-blah". I have a section in my JSP that will catch and display these.

So here's the rub: When I have no report to send, I don't call the above function. But I always call something like:

return mapping.findForward("pullReports");

as the last line in my ActionForward method and the errors appear. However, if I have bits to send via the streamFileToBrowser() function, my eventual call to mapping.findForward does nothing.

A bit of digging tells me that Struts is only able to handle one response to the HttpServletResponse object at a time. I've used it with my call to streamFileToBrowser(), so the eventual call to mapping.findForward(...) does nothing as far as my client is concerned.

Anyone else run into this and found a solution?


Solution

  • What I've done is to make sure that to the extent that it's possible, all errors get caught before the PDF generation begins. That way you can send back a plain old set of form errors, or whatever. Once you've started sending back an attachment like that, the browser isn't going to pay attention to anything else. If you absolutely can't find errors before you get into generating the PDF file, I think the only thing you can do is to embed the error messages in the PDF itself (unpleasant, I know).