I think the general idea is good. Struts comes with an "upload" example, so there should be a "download" example, if there is not one already. So I'll start with some constructive criticism.

If I understand your code correctly, you are loading all the bytes of the file (or BLOB) into memory at once, without good reason (a good reason might be if several objects were editing an XML document before it was to be served).

I would use a variable (but small) buffer size. Then I would read from the source (file) until the buffer is filled. Then I would empty the buffer to the destination (response output stream) before reading any more from the source into memory. Repeat until finished. In other words, stream the content.

Also, I would pay more attention to response header fields.

Here is a partial example of serving a PDF (from the filesystem) to be viewed inline:

InputStream in = null;
OutputStream out = null;
try {
 File pdf = new File("/home/eweber/doc/jsp_card12.pdf");
 response.setContentType("application/pdf");
 response.setHeader("Cache-Control", "max-age=600");
 StringBuffer cd = new StringBuffer();
 cd.append("inline");
 cd.append("; filename=");
 cd.append(pdf.getName());
 response.setHeader("Content-disposition", cd.toString());
 response.setContentLength((int) pdf.length());
 in = new FileInputStream(pdf);
 out = response.getOutputStream();
 int bytesRead = 0;
 byte[] buffer = new byte[8192];
 while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
   out.write(buffer, 0, bytesRead);
 }
 out.flush();
}
// probably want to return null if this is in Action.execute


Here are some comments from fellow Struts user Daniel Perry on the header fields (except Content-type):


<snip>

Daniel Perry wrote:

They effect browser behaviour.

cache-control - used by browsers and proxies to determine wether to cache
the document or not, and if so, for how long.

content-length - not sure if struts would do this for you, but i know there
are issues with some browsers not liking binary data that it doesnt know the
length of. Especially applies to pdfs.


Content-disposition - this is *very* usefull. You can specify inline or
attachment. Inline tells the browser to display the file in the browser.
(eg. the normal default behaviour for pdfs). Attachment tells the browser
that the file is to be downloaded rather than viewed, so the browser should
show the 'save file' dialog box. Using filename=... with this allows you to
specify a filename for the attachment. So, if you have an action
download.do?id=6, it can say filename is tradereport-march-2004.pdf! Very
useful for reports, etc where you would otherwise have many files with the
same 'default' filename, ie report.pdf/whatever the browser decides. Can be
used to reduce admin cockups!!!


Daniel.

</snip>


Hope that helps, Erik


Frank W. Zammetti (MLists) wrote:

I posted this a few days ago to the Struts dev list... I only got one
response, which I think either means (a) we're too busy to look at this
right now, or (b) this is stupid, go away.  I'm OK with either answer, but
I thought maybe posting it here would be a good idea, especially if the
answer is (b), I should find that out pretty quickly :)

One of the things I see asked very frequently is how to return PDF's and
other BLOB fields from a database (or from a file system).  People seem to
either have trouble figuring out how to do it and require help, or have
trouble making it work.

Please find attached source for a new Action called BLOBAction that I
submit to you all for comments and, perhaps eventually, inclusion in
Struts as a built-in Action like ForwardAction and the like.

Consider this proof-of-concept code, quality-wise... You can read my
rather verbose comments on this, but in short... Right now it works by
accepting a bunch of parameters submitted with the request.  This I feel
is NOT the right approach.  I was hoping that Struts would read in unknown
attributes for <action> mappings from struts-config.xml, but that does not
seem to be the case.  I believe most, if not all, of these parameters
should become attributes of the action mappings themselves, but this is
one of the things I'm looking for feedback on.

I am using this code (essentially this code... this is more generic
though) in a production app here at work, so I know it works (aside from
my tests here on this particular code which of course work).  I'm sure
it's not ready as-is, but I don't think it's too bad either.

It's not revolutionary or anything, but I think it is a solution to a
pretty generic problem and might be a good thing to be included with
Struts (or I might be completely wrong!  I don't discount that
possibility)  I look forward to any comments you may have (first and
foremost: is this even worth it?  I think it is, but I may be wrong on
even that basic point!)



------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to