Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem forwarding PDF to browser

Status
Not open for further replies.

PJDez

Programmer
Apr 1, 2004
5
US
I've been searching for a solution to a problem I am having with forwarding PDF output to the user. I am using exact code from another application that uses JRun. What happens is a new window is opened and I receive a File Download prompt. No matter what option I select, the process fails. I've tried this in IE 6.0 and Netscape 7.1 and Netscape works - the new window displays the generated pdf. Here's the code:

In execute() method:
Code:
    ByteArrayOutputStream bos = new ByteArrayOutputStream(5000);
    //Obtain the BLOB from the database and generate a PDF
    PDFiText report = new PDFiText(selectText(passedGENLTRID), bos);
    httpServletResponse.setContentType("application/pdf");
    httpServletResponse.setContentLength(bos.size());
    OutputStream os = httpServletResponse.getOutputStream();
    os.write(bos.toByteArray(), 0, bos.size());
    os.flush();
    os.close();
    return null;
I use iText to generate the PDF and it takes in a Document and an OutputStream. This code works in a production environment using JRun instead of Tomcat and Struts. This also works flawlessly under Netscape 7.1, but IE 6.0 is the only supported browser in our company.

Does anyone have any idea why this isn't working in IE? I've tried various versions of this code, including reading a pdf file instead of writing from an output stream. I've also tried setting the header on the response using this code:
Code:
httpServletResponse.setHeader("Content-Disposition","attachment; filename=somefilename.pdf");
Thanks,
Patrick Dezenzio
 
Hi,

I am not sure with answer, but did you try with BufferedOutputStream and BufferedInputStream.


Code:
 InputStream in = null;
 OutputStream out = null;
 try {
  in =  new BufferedInputStream(inputStream);
  out = new BufferedOutputStream(resp.getOutputStream());
  content_len = (int) in.length();
  resp.setContentType("octet-stream");
  resp.setContentLength(content_len);
  resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
  while ((len = in.read()) != -1) {
      out.write(len);
   }

Hope this will help you..

Cheers
Venu
 
Tried it and got the same results with IE, but Netscape took it just fine. Anyone else have any ideas?

Thanks,
Patrick
 
I found the problem! It isn't in the way the output stream is setup in the action. Remember, I had said I opened a new window in my jsp. I used script to tailor the forward and the use of javascript:void(window.open(...)) caused IE to act on that new window. Now I could do what you all are thinking right now and that's to keep the pdf in the same window.

The problem is this system will mimic the production system (old Java code that is about as difficult to maintain as Assembler code) and the users are used to seeing their pdf letters in a separate window. They print them and close the window and then it's off to the next transaction. If I alter their workflow in a way that causes them to close out the main browser, that won't be good. So I can compromise maybe. Either figure out a way to open a separate window that actually works or set their Adobe Reader to not open in a browser.

If anyone has a suggestion as to how to open a new window that doesn't cause IE to get so picky, let me know. Here's the script and code I use:

Code:
    function doConvert(aItem1) {
      aBase = '/indblue/appViewLetter.do';
      var newItem = '';
      for (i = 0; i < aItem1.length; i++) {
        if (aItem1.charAt(i) != '{' && aItem1.charAt(i) != '}' && aItem1.charAt(i) != ' ' && aItem1.charAt(i) != ',')
          newItem += aItem1.charAt(i);
        if (aItem1.charAt(i) == ',')
          newItem += '&';
      }
      return(aBase + '?' + newItem);
    }

What the code is doing is taking the argument expression "{'GRNLTR_ID=4,APP_ID=5'}" and reformatting it to look like "GRNLTR_ID=4&APP_ID=5". Here's the code that uses this script:

Code:
<a href="javascript:void(window.open(doConvert('<bean:write name='letterval' property='letterParamsToPass'/>')))">
               <html:img src="./images/ViewLetter.gif" border="0" alt="View Letter"/></a>

letterval is the name of a select using the logic:iterate tag which enables the code to be very streamlined and easy to maintain. The property letterParamsToPass points to the getter method in the Row form that is used to keep track of the data in the select. This getter method returns a HashMap. The code that we use to format the parameter list in the forward looks like this:

Code:
<html:link page="/appViewLetter.do"
                          name="letterval"
                          property = "letterParamsToPass">
               <html:img src="./images/ViewLetter.gif" border="0" alt="View Letter"/>
               </html:link>

This code automatically formats the url to forward the request to the appViewLetter action with the parameters GRNLTR_ID=4&APP_ID=5. So you see why I had to reformat the parameter signature.

I'll try looking at ways to open a new window, but at worst, I have a way to open a pdf document is a separate window.

Thanks,
Patrick
 
Well I feel stupid. I don't need to go thru all that trouble. If you need to open a page in a new window you use "javascript:void(0)" onclick=" OR href=" target="_blank". Here's the final change that uses the Struts framework with no hacks or Javascript:

Code:
   <logic:iterate id="letterval" type="org.bcbsal.indblue.forms.AppInfoLetterRowForm"
                                name="applicationInfoForm" property="applicationLettersList">
  <tr>
   <td><html:link page="/appViewLetter.do"
                          name="letterval"
                          property = "letterParamsToPass"
                          [b][COLOR=red]target="_blank">[/color][/b]
               <html:img src="./images/ViewLetter.gif" border="0" alt="View Letter"/>
               </html:link>
           </td>
           <td><html:link page="/appEditLetter.do"
                          name="letterval"
                          property = "letterParamsToPass">
               <html:img src="./images/EditLetter.gif" border="0" alt="Edit Letter"/>
               </html:link>
           </td>
           <td><html:link page="/appDeleteLetter.do"
                          name = "letterval"
                          property="letterParamsToPass">
               <html:img src="./images/DeleteLetter.gif" border="0" alt="Delete Letter"/>
               </html:link>
           </td>
           <td><bean:write name="letterval" property="letterTmpltLabel"/></td>
   </tr>
  </logic:iterate>

That took just one additional property. I only wished I looked at the html:link syntax more closely. It took a fair bit of research to find that target is an option. Oh well, hopefully my time spent will help others:)

Thanks,
Patrick
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top