FileInputStream.available() is only guaranteed to tell you how many
bytes are immediately available for reading without blocking --
probably one buffer worth. You need to copy *all* of the bytes to the
output stream -- something like this (but doing it from memory so
might not be correct):
FileInputStream in = new FileInputStream(pdf_path);
OutputStream out = ...; // whatever output stream you want
byte buffer[] = new byte[BUFFER_SIZE];
int bytes;
while (true) {
bytes = in.read(buffer, 0, BUFFER_SIZE]);
if (bytes < 0) {
break;
}
out.write(buffer, 0, bytes);
}
out.flush();
out.close();
in.close();
Define BUFFER_SIZE based on a balance between memory occupancy and
speed -- probably something like 4096 would serve as a good starting
point, especially if your PDFs are small and might fit in a single
buffer.
Craig
On Wed, 4 Aug 2004 10:37:18 +0200 , Otto, Frank <[EMAIL PROTECTED]> wrote:
> Hi,
>
> I have written an action class to show the pdf, but the pdf is corrupt.
>
> Do I something wrong?
>
> ....
> FileInputStream fis = new FileInputStream(pdf_path);
> int anz = fis.available();
> byte[] data = new byte[anz];
> fis.read(data);
>
> ByteArrayOutputStream baos = new ByteArrayOutputStream();
> baos.write(data, 0, anz);
> baos.flush();
> baos.close();
>
> response.setContentType("application/pdf");
> response.setHeader("Pragma", "public");
> response.setHeader("Content-Disposition", "inline;filename=offer.pdf");
> response.setContentLength(anz);
>
> ServletOutputStream out = response.getOutputStream();
> baos.writeTo(out);
> out.flush();
> ....
> return null;
>
> kind regards,
>
> frank
>
> > -----Urspr�ngliche Nachricht-----
> > Von: Frank Zammetti [mailto:[EMAIL PROTECTED]
> > Gesendet: Dienstag, 3. August 2004 15:41
> > An: [EMAIL PROTECTED]
> > Betreff: RE: struts and iText
> >
> >
> > Another option: write the PDF out to a database BLOB field,
> > then create an
> > Action to retrieve that field. This I think gives you the
> > best of all
> > worlds. If you structure the table properly, you can share
> > the PDF across
> > various requests/users and you can even avoid PDF generation
> > potentially by
> > seeing if an appropriate PDF exists in the table already. A
> > simple timed
> > stored procedure should serve as a good cleanup mechanism.
> > Just to save you
> > some time, here's an Action I use in a system I wrote that
> > retrieves any
> > BLOB field and returns it... I'll have to remove some parts
> > and just give
> > you comments because it uses two custom classes for database
> > access, and I
> > don't want to post that much code here, the other classes are a bit
> > larger... I'll also simplify the error handling, since it's
> > custom as well,
> > but I think the point will come across... The only note I
> > think is that
> > this assumes that the table the BLOB is retrieved from has a
> > field with the
> > same name as the BLOB field with _ctype appended, and this
> > contains the
> > content type to return.
> >
> >
> > import java.io.ByteArrayOutputStream;
> > import java.sql.Blob;
> > import javax.servlet.http.HttpServletRequest;
> > import javax.servlet.http.HttpServletResponse;
> > import javax.servlet.ServletOutputStream;
> > import org.apache.struts.action.Action;
> > import org.apache.struts.action.ActionForm;
> > import org.apache.struts.action.ActionForward;
> > import org.apache.struts.action.ActionMapping;
> >
> > public class BLOBServerAction extends Action {
> >
> > public ActionForward execute(ActionMapping mapping,
> > ActionForm inForm,
> > HttpServletRequest request, HttpServletResponse response)
> > throws Exception {
> >
> > try {
> >
> > String bTable = "the_table_the_blob_is_in";
> > String bField = "the_field_the_blob_is_in";
> > String bQuery = "where_clause_to_select_proper_record;
> >
> > String sql = "select " + bField + "," + bField +
> > "_ctype from " +
> > bTable + " where " + bQuery;
> > Blob blob = null;
> > String contentType = null;
> > byte[] bytes = null;
> >
> > ResultSet rs = doSelect(sql); // Insert database access
> > here, just use
> > the above constructed SQL string
> > while (rs.next()) {
> > contentType = rs.getString(bField + "_ctype");
> > blob = rs.getBlob(bField);
> > }
> >
> > ServletOutputStream out = response.getOutputStream();
> >
> > response.setContentType(contentType);
> > if (blob != null) {
> > bytes = blob.getBytes(1, (int)(blob.length()));
> > ByteArrayOutputStream ba = new ByteArrayOutputStream();
> > ba.write(bytes, 0, bytes.length);
> > ba.writeTo(out);
> > }
> > out.flush();
> >
> > } catch (Exception e) {
> >
> > e.printStackTrace();
> >
> > }
> >
> > return null;
> >
> > } // End process()
> >
> > }
> >
> >
> > Hope that helps, if you go this route.
> >
> > Frank W. Zammetti
> > Chief Software Architect
> > Omnytex Technologies
> > www.omnytex.com
> >
> >
> > >From: "Jesse Alexander (KXT)" <[EMAIL PROTECTED]>
> > >Reply-To: "Struts Users Mailing List" <[EMAIL PROTECTED]>
> > >To: Struts Users Mailing List <[EMAIL PROTECTED]>
> > >Subject: RE: struts and iText
> > >Date: Tue, 3 Aug 2004 10:49:08 +0200
> > >
> > >Well,...
> > >
> > >If you already have the PDF generated, why not directly
> > write it to the
> > >response(and in this way to the browser)?
> > >
> > >To fulfill your use case as described.
> > >Your action generates the PDF and caches it somewhere. Then
> > it will forward
> > >to the JSP-File containing the message and the link. This
> > link either
> > >points to a Struts-Action or a plain servlet. This
> > target-Servlet (or
> > >Action) retrieves the cached PDF and sends it to the browser.
> > >Where to cache?
> > >a) File-System
> > > - you need a writable location and remember to install
> > some cleaning
> > >mechanism
> > > - the link presented could be just the reference to the
> > cached file if
> > >that directory
> > > readable by the webserver
> > >b) user-session
> > > - dangerous in a clustered environment (too much stuff to
> > propagate
> > >around)
> > > - memory usage (usually the recommendation is not to use
> > more than 4K in
> > >session...)
> > > - PDF only available to original user
> > > - easy to program
> > >c) separate cache
> > > - adds another component to your app (DO NOT roll your own
> > cache, there
> > >are quite a
> > > number of tested cache-libraries)
> > > - could make the PDF available also to other users (depends on the
> > >use-case and the
> > > cache-library)
> > >
> > >hope this helps
> > >Alexander
> > >
> > >
> > >-----Original Message-----
> > >From: Otto, Frank [mailto:[EMAIL PROTECTED]
> > >Sent: Tuesday, August 03, 2004 9:18 AM
> > >To: '[EMAIL PROTECTED]'
> > >Subject: struts and iText
> > >
> > >Hi,
> > >
> > >I have generated a pdf with iText. In my action class I want
> > to write it in
> > >the response object.
> > >
> > >The result should be a jsp-page with content "pdf generated
> > successful" and
> > >a link to this pdf. The pdf should be shown in a new browser
> > window too.
> > >
> > >Has someone do this? How can I do this?
> > >
> > >
> > >kind regards,
> > >
> > >frank
> > >
> > >---------------------------------------------------------------------
> > >To unsubscribe, e-mail: [EMAIL PROTECTED]
> > >For additional commands, e-mail: [EMAIL PROTECTED]
> > >
> >
> > _________________________________________________________________
> > Planning a family vacation? Check out the MSN Family Travel guide!
> > http://dollar.msn.com
> >
> >
> > ---------------------------------------------------------------------
> > 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]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]