Any time!
Virtually, Andre Van Klaveren, SCP On Mon, 14 Mar 2005 14:51:37 -0600, Brad Balmer <[EMAIL PROTECTED]> wrote: > Thanks for the great response. This should take care of all my issues. > > -----Original Message----- > From: Andre Van Klaveren [mailto:[EMAIL PROTECTED] > Sent: Monday, March 14, 2005 2:39 PM > To: Struts Users Mailing List; [EMAIL PROTECTED] > Subject: Re: Output PDF > > I'm assuming that your browser client is IE. If so, the reason your > Action is being called twice is because of a "feature" in IE 4.x+. If > your application returns data that is to be handled with an ActiveX > control (ie Adobe Acrobat Reader) the browser sends additional > requests to the server. In IE 4.x and 5 it actually sends three > requests. For IE 5.5+ it sends two. > > Assuming that your using IE 5.5+, the first request is the original > request (duh), but then IE sends a second request to get the > content-type. Who knows why they can't figure this out on the first > request ;) This second request has it's userAgent header set to > "contype". You can solve this problem and increase the performance of > your application by writing a Servlet filter that sits in front of > whatever Actions you have setup to serve PDF content. Have this > filter look at the userAgent header of each request. If it's set to > "contype" just send an an empty response back to the client with the > content type set to "application/pdf". Simple as that. > > Now, the reason your getting an exception in the second code snippet > you provided is because after you do your forward the JSP calls > response.getOutputStream(). This is done behind the scenes but you > can see it if you look at your generated Servlet code. This method > can only be called once during the lifestyle of the request, hence > your exception. > > It's generally a bad idea to have a JSP produce binary content anyway. > They were designed for Text or HTML output. > > I wrote a generic/reusable Servlet whose sole purpose in life is to > write binary content back to a client. I called it > BinaryOutputServlet. You put your binary data (byte[]) and the > content type of the data in the request scope and forward to it. It > gets the data and content type out of the request and writes it back > to the client. It can be used for any type of data this way. I would > recommend doing something similar since Actions are really for > control. By writing back to the client from an Action you are > violating the MVC model anyway. > > I hope this helps. Oh, and you can read all about the "feature" of IE here: > http://support.microsoft.com/default.aspx?scid=kb;EN-US;q293792 > > Virtually, > Andre Van Klaveren, SCP > > On Mon, 14 Mar 2005 14:01:48 -0600, Brad Balmer <[EMAIL PROTECTED]> wrote: > > I'm using Jasper to create PDF's through my Actions and cannot figure out > a > > good way to export the resulting byte[] to the user. > > > > Currently the tail end of my Action class looks like this: > > > > byte[] reportBytes = null; > > > > File jasperReport = new File(location); > > > > try { > > > > reportBytes = JasperRunManager.runReportToPdf(jasperReport.getPath(), > > parameters, dataSource); > > > > log.info("Found : " + reportBytes.length); > > > > } catch (JRException e) { > > > > e.printStackTrace(); > > > > } > > > > response.setContentType("application/pdf"); > > > > response.setContentLength(reportBytes.length); > > > > ServletOutputStream ouputStream = response.getOutputStream(); > > > > ouputStream.write(reportBytes, 0, reportBytes.length); > > > > ouputStream.flush(); > > > > ouputStream.close(); > > > > return(null); > > > > This will display the pdf, but the action class itself somehow get called > a > > second time as the above log statement is displayed twice. > > > > I also tried to set the byte[] on the request and forward onto another > page > > which does: > > > > <% > > > > byte[] reportBytes = > > (byte[])request.getAttribute("REPORT_BYTES"); > > > > response.setContentType("application/pdf"); > > > > response.setContentLength(reportBytes.length); > > > > ServletOutputStream ouputStream = response.getOutputStream(); > > > > ouputStream.write(reportBytes, 0, reportBytes.length); > > > > ouputStream.flush(); > > > > ouputStream.close(); > > > > %> > > > > But this complains about: getOutputStream() has already been called for > this > > response > > > > Any ideas? > > > > > > -- > Virtually, > Andre Van Klaveren > SCP > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > -- Virtually, Andre Van Klaveren SCP --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]