struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Scott Piker" <scott.pi...@xede.com>
Subject RE: Output PDF
Date Mon, 14 Mar 2005 21:21:25 GMT
This intrigued me, since our app also has some generated PDFs.  Sure
enough, there's a double-get occurring w/ our IE clients (IE 6.0).  

Problem is that the "USER_AGENT" header for get #1 & #2 are identical.
In fact, the only difference I can see in all headers is that get #1 has
an "ACCEPT-LANGUAGE" header, whereas get #2 does not.  Everything else
is the same

So what gives?  Did MS "fix" the wrong end of this bug in IE6?  Is it
safe to just look for the existence of the "ACCEPT-LANGUAGE" header?

Thanks,
- Scott


-----Original Message-----
From: Andre Van Klaveren [mailto:nybbas@gmail.com] 
Sent: Monday, March 14, 2005 3:39 PM
To: Struts Users Mailing List; bbalmer@peapod.com
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 <bbalmer@peapod.com>
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: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Mime
View raw message