File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Struts and the fly likes open a pdf inline using MIME in ie7 Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "open a pdf inline using MIME in ie7" Watch "open a pdf inline using MIME in ie7" New topic
Author

open a pdf inline using MIME in ie7

Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
I am trying to open a pdf file inline. It works when I set the content disposition to attachment but not when I specifiy inline. I have been asked to make the pdf automatically open without the user prompted to select open, save, etc.

I have been searching for an answer all day and have tried changing the content disposition, etc. I am starting to wonder if it is possible at all. I checked IE7 site and it does support the pdf MIME type.

Any help is appreciated. Here is my code:

//---------------------------------------------------------------
// Set the output data's mime type
//---------------------------------------------------------------
response.setContentType( "application/pdf" ); // MIME type for pdf doc
response.setHeader("Content-disposition","inline; filename=bill.pdf" );
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

response.setHeader("Content-disposition","inline; filename=bill.pdf" );

I don't think it matters but it should be 'Content-Disposition' (upper case D).

How are you delivering the PDF?
Are you streaming the bytes?

Have you verified that your browser has Acrobat configured as the associated application for that mime type?


Java API J2EE API Servlet Spec JSP Spec How to ask a question... Simple Servlet Examples jsonf
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Thanks, the upper case D did not seem to make a difference but thanks, I changed it.

I am writing out a buffered stream, see code below:

"Have you verified that your browser has Acrobat configured as the associated application for that mime type?"

I have not done this but if I need this to automatically open on any client...would I be able to control that?


Thank you.

[BPSouther: Added code tags]
[ January 11, 2008: Message edited by: Ben Souther ]
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Also, I left out a vital piece of information. It starts to download the pdf:
10:05:50,987 INFO [STDOUT] Kate counter=1024-----291
10:05:50,987 INFO [STDOUT] Kate counter=1024-----292
10:05:50,987 INFO [STDOUT] Kate counter=793-----293


Then the browser just goes blank and says it is done. I have searched a ton of posts with the same issue but none of the proposed solutions have worked for me.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Can you explain what this line does:
and why it's there.

Also, what are you using for the "out" variable to which you're writing?
Is it a reference to the servletOutputStream?

Did you say that this code is working in other browsers?
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
I have not really figured out what it is for because I did not write that part but I can tell you that it does not matter whether it is there or not and I plan to remove it.

The variable "out" is a reference to the servletOutputStream. I also tried a reference to outputStream just for fun.

Either reference works as as long as my Content-Disposition is "attachment". The problem is that I have been asked to have the pdf render in the browser and not prompt the user with adobe. I am trying to accomplish this by changing the Content-Disposition to "inline".
When I change it from "attachment" to "inline", the datastream is written but the browser remains as a blank page.

Thanks for your response.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Actually I am wrong, it does not work as an attachment if I take this line out "if ((bytesRead != 1024) && (counter > 261))break;". Thanks, I think that is the culprit.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Sorry, just want to make it clear that I have not found the solution but know the "if ((bytesRead != 1024) && (counter > 261))break;" is a problem since it does not work without that line.

Once I figure it out, I will post the solution. Thanks for your help in getting me in the right direction.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

If it will help, there is a demo app in our CodeBarn under the servlet section called simple stream that contains code for streaming binary content to the browser.

In that app it's streaming images, but (other than setting the content type) it should work the same for PDFs.

It might be easier to work on this problem from a separate, small app until it's done. Modifying that app would be an easy way to do that.

It's packaged as a war file so all you need to do is drop it into the webapps directory of a running Tomcat instance and it will auto-deploy itself.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Well, I figured out the problem. The line "// if ((bytesRead != 1024) && (counter > 261))break; " was added so that when the pdf was done downloading it would break out of the loop because the while loop is not working.

In looking at the BufferedInputStream, shouldn't it return the number of bytes read and then a -1 when it is the end of file ? The while statement "while(-1 != (bytesRead = bis.read(buffer, 0, buffer.length))" is failing because it does not return a -1 to let me know it is the end of file.

If I print the following " System.out.println("Kate="+(bytesRead = bis.read(buffer, 0, buffer.length))); ", I will get 1024(the total bytes) until the end of file then I will get some random number that is less than 1024?

I must not fully understand something? Thanks.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Did you look at the code sample that I mentioned earlier?
http://faq.javaranch.com/java/CodeBarnSimpleStream

I've used this code in dozens of places to stream files (including PDFs) without any problems.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
I did thanks, it still has the same problem of hanging when I take the break out. Here is the code now:

in = new DataInputStream(soc.getInputStream());

ServletOutputStream out = response.getOutputStream();




//---------------------------------------------------------------
// Set the output data's mime type
//---------------------------------------------------------------
response.setContentType( "application/octet-stream" ); // MIME type for pdf doc


//------------------------------------------------------------
// Content-disposition header - don't open in browser and
// set the "Save As..." filename.
// *There is reportedly a bug in IE4.0 which ignores this...
//------------------------------------------------------------

response.setHeader("Content-Disposition", " inline; filename=bill.pdf" );

// response.setHeader("Content-Disposition","attachment; filename=bill.pdf" );

//-----------------------------------------------------------------
// PROXY_HOST and PROXY_PORT should be your proxy host and port
// that will let you go through the firewall without authentication.
// Otherwise set the system properties and use URLConnection.getInputStream().
//-----------------------------------------------------------------


// Use Buffered Stream for reading/writing.
byte[] buffer = new byte[4 * 1024];
bis = new BufferedInputStream(in, buffer.length);
int data;
long start = System.currentTimeMillis();
long current = 0;

// Simple read/write loop.

while((data = bis.read(buffer)) != -1)
{
out.write(buffer, 0, data);
}
out.flush();




if (bis != null)
bis.close();
if (out != null)
out.close();

} catch(Exception e){
e.printStackTrace();
}

return NONE;

}
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
What do you think of this idea since my code and the barn code are giving me the same result? There is code above mine that actually pulls this file from an archive off the network. Maybe this code is not writing some kind of eof indicator? When I write out "System.out.println("Kate="+ (bis.read(buffer)));", it never does return a -1? Here is the code that pulls the information from the archive:


[ January 15, 2008: Message edited by: Ben Souther ]
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Try this one and see if it works.
If it does, compare the code with what you've got.

If you change your code to match mine and it still doesn't work (but mine does) than the problem is most likely whatever is generating your PDFs.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Our last two post criss crossed.

So your application is dropping to socket level to retrieve the PDF and (for some reason) is getting 1024 as the EOF character instead of -1.
Your app starts checking for this after the 261st byte and stops reading/writing the bytes.

And.. this is, working as an attachment but not inline, right?
If so, does Acrobat report any errors when opening the PDF?
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
I think when it does each read it returns 1024 bytes and then the last read it drops to less than 1024. So, the code is saying when it is not 1024 bytes break out of the loop. This is working as an attachment but not inline. Acrobat does not report any errors that are popping up but I will look for a log.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
I am not finding an error log and there are no errors when opening the pdf.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Just for clarity sake, I am guessing someone before me found that this was not returning a -1 so rigged it to work. If I take the break out and write out what the read is returning, I get the following:
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,059 INFO [STDOUT] What are we writing=1024
09:31:55,559 INFO [STDOUT] What are we writing=1024
09:31:55,559 INFO [STDOUT] What are we writing=842

I would think that the last read should return a -1?

Also, if I do this (take out the break) the adobe shows it is trying to download and just sits there hanging and trying to copy. It never goes to "verifying".

Thanks for working with me.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

I'm running out of ideas.

The only guess that I have is that the length of the stream doesn't match what's in the header and that this is throwing off MSIE but Acrobat is working around this when it comes down as an attachment.

If you'd like, I can move this to our Socket's and internet protocols forum.
Maybe someone there can figure out why you're not getting a proper EOF character to begin with.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Thank you, that would be nice. I appreciate all of your help. I have one more question for you, did you use the code from the code barn on ie7?
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Yes, I've tried the simpleStream app and the pdf.war app that is linked to earlier in this thread.

They both worked in IE7
[ January 15, 2008: Message edited by: Ben Souther ]
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Thank you for all of your help.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Moving to sockets and internet protocols.
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

Originally posted by Katie Doody:

. . .
09:31:55,559 INFO [STDOUT] What are we writing=1024
09:31:55,559 INFO [STDOUT] What are we writing=842

This is correct. Your output will probably not be evenly divisible by 1024 so there will be at least one output that has fewer bytes.

Originally posted by Katie Doody:

I would think that the last read should return a -1?

Not if your print statement is inside the while loop.

What are you reading this PDF file from? I agree with Ben's assessment of 6:22 PM yesterday where he states that the problem is most likely whatever is generating the PDF file.


"blabbing like a narcissistic fool with a superiority complex" ~ N.A.
[How To Ask Questions On JavaRanch]
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
It is coming off of a archive server through a socket. Here is the code that gets it off the server:
byte[] utf8BytesFormattedReqHeader = {0,0,3,0,0,0,0,0};

os = new DataOutputStream(soc.getOutputStream());
in = new DataInputStream(soc.getInputStream());


//Preparing Request

StringBuffer sbRequest = new StringBuffer("M=2&Account=");
sbRequest.append(strAcctNum).append("&Date=").append(strDate);
sbRequest.append("&D=2&HTTP=0&Page=1&N=1000");
String sRequest = sbRequest.toString();

//Preparing Header
int totalRequestLength = sRequest.length()+8;
byte[] utf8BytesTotalLength = (String.valueOf((char)totalRequestLength)).getBytes("UTF8");
utf8BytesFormattedReqHeader[0] = utf8BytesTotalLength[0];
byte[] utf8BytesRequestLength = (String.valueOf((char)(totalRequestLength-8))).getBytes("UTF8");
utf8BytesFormattedReqHeader[6]=utf8BytesRequestLength[0];
printBytes(utf8BytesFormattedReqHeader, "a1");

//Sending byte format request
os.write(utf8BytesFormattedReqHeader);
os.write(sRequest.getBytes("UTF8"));
os.flush();

ServletOutputStream out = response.getOutputStream ();
// FileInputStream in = new FileInputStream(destinationFile);
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

What is on the archive server responding to your request?
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
We get a binary string back that is in a pdf format. I don't know enough about this third party box. We send a request in binary string and we get a binary string back.
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

This "binary string" is the variable "in" in your code?
Either you aren't using the correct protocol to communicate with that server or they aren't closing their end of the socket to send you an EOF. I'd suggest finding someone who knows more about that server.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
I tried that route...looks like I am lucky one. It gives me a path to pursue though. Thanks.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Hello, I have tried this same code with a .pdf on my local machine and it works for attachment but not for inline. I now believe it has something to do with that fact that I am using struts2.
"extends ActionSupport implements ServletRequestAware, ServletResponseAware".

Do you think somebody can move me over to struts to see if anybody has run into this situation? Thanks.
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

Try putting an os.close() after your os.flush().
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
No luck. For simplicity, I am just trying to display a file on my local. I can successfully display it when I use Content-Disposition of "attachment" but get a white page when I try "inline". Here is my code now:

public class MyBillClass extends ActionSupport implements ServletRequestAware, ServletResponseAware {

private HttpServletRequest request;
private HttpServletResponse response;





/** Creates a new instance of MyBillClass */
public MyBillClass() {
}

public String execute() throws Exception {

try{





///try this
String filename = "bill.pdf";


// Set Content type
String contentType;

contentType = "application/pdf";


// Stream the image
BufferedInputStream in = null;

in = new BufferedInputStream(
request.getSession().getServletContext().
getResourceAsStream("WEB-INF/bill.pdf"));

response.setContentType(contentType);
response.setHeader("Content-Disposition", "inline; filename=" + "bill.pdf");

ServletOutputStream out = response.getOutputStream();

byte[] buffer = new byte[4 * 1024];

int data;
while((data = in.read(buffer)) != -1)
{
out.write(buffer, 0, data);
}
out.flush();
out.close();


} catch(Exception e){
e.printStackTrace();
}

return NONE;

}
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

I dropped that code into the struts 2 blank application and it worked fine (I tested IE7 and Firefox 2.0.0.1 on WinXP):

Can you open other PDF's inline?
Have you tried another browser?
Tried the same code on another computer?
Are you running XP or Vista?
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Can you open other PDF's inline?
Have you tried another browser?
Tried the same code on another computer?
Are you running XP or Vista?

I tried another pdf that I stuck on my local and it does work ...? Ahh, I think I just took a breathe .
I have not tried another browser but I might stick the war on the linux box and see if it works.
Nope, I have not tried the code on another box.
My machine is running XP.
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

Originally posted by Katie Doody:

I tried another pdf that I stuck on my local and it does work ...?


So the problem is the PDF file?
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Now that I know that it has something to do with the pdf. I have found the struts 2 way to do it...well, it works. Please correct me if anyone sees anything wrong.

MyAction:

public class MyAction extends ActionSupport implements ServletRequestAware, ServletResponseAware {

private HttpServletRequest request;
private HttpServletResponse response;


/** Creates a new instance of MyAction */
public MyAction() {
}

public String execute() throws Exception {



try {

imageStream = request.getSession().getServletContext().
getResourceAsStream("WEB-INF/bill.pdf");


} catch(Exception e){
e.printStackTrace();
}

return "SUCCESS33";

}

public void setServletRequest(HttpServletRequest httpServletRequest) {
this.request = httpServletRequest;
}

public void setServletResponse(HttpServletResponse httpServletResponse) {
this.response = httpServletResponse;
}

public HttpServletRequest getServletRequest() {
return this.request;
}

public HttpServletResponse getServletResponse() {
return this.response;
}

/** Return an InputStream for the StreamResult */
public InputStream getImageStream() {
return imageStream;
}


}


struts.xml:

<action name="MyAction" class="com.mudnebr.cwa.action.MyAction" >
<result name="SUCCESS33" type = "stream">
<param name="contentType">application/pdf</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">filename="bill.pdf"</param>
<param name="bufferSize">1024</param>
</result>
<result>/tiles/keepScreen.jsp</result>
</action>
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Well, I found my issue with the difference between the good pdf and the bad pdf (the one my third party system is generating). If I open them both with word, the good one starts with %PDF-1.1 and ends with 95468
%%EOF. The bad one starts with <� %PDF-1.3%���� and ends with 296516
%%EOF. You can't really see from this but I think the issue is the hard returns. If I remove the hard returns at the beginning of the bad one, the page renders perfectly.

The hard return at the end of this also may explain why I am not getting the eof since it does not display %%EOF on the last line on its own.

I think since the %PDF is not the first thing to display in the pdf, the browser is having issues knowing how to render the page.

I am not sure how I will fix this but I have found the issue. I would be very open to any ideas.
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8908
    
    8

What do you mean by "hard returns"? Exactly what are you removing to make the bad file work?
Word probably isn't the best tool to examine a binary file. You should probably use a hex editor. It lets you see exactly what values a file contains. Word may hide values thinking they are control characters.
I'm going to stand by my comment of 1-15 at 12:58 PM. I think your third-party server or the way you interface with it is the problem.
Have you saved the file exactly as it is produced by the third party app? Maybe Struts could be throwing a character or two in there.
Katie Doody
Ranch Hand

Joined: Nov 03, 2006
Posts: 90
Here it is in Hex:
I am removing everything before the %PDF in this line "00000000:00 00 00 00 3c 90 04 00 25 50 44 46 2d 31 2e 33 ....<�..%PDF-1.3".

I am also putting %%EOF on it's own line in this line "00049030:72 74 78 72 65 66 0a 32 39 36 35 31 36 0d 25 25 rtxref.296516.%%
00049040:45 4f 46 0a EOF."

I think it is probably the third party server as well but all we can send is a binary request to this server with the account number, etc. and it returns the pdf.

I saved the file by using the Content-Disposition of attachment. The files are stored on that server as a .drd. I am not sure what that even is but the process on the "black hole" converts it to a pdf.

I am beginning to believe there are some things you just can't control. I really appreciate your help.

Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Out of curiosity, is this 'black box' a third party product or something that was written in house? It appears that you've done a nice job of isolating a bug for whomever wrote it.
Can you submit a bug report to someone?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: open a pdf inline using MIME in ie7