It's not a secret anymore!*
The moose likes Servlets and the fly likes Serving PDF with my servlet - performance & non-display Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "Serving PDF with my servlet - performance & non-display" Watch "Serving PDF with my servlet - performance & non-display" New topic
Author

Serving PDF with my servlet - performance & non-display

Monty Guppy
Ranch Hand

Joined: Sep 15, 2001
Posts: 49
Hi,
I have my PDF file loaded as binary in the database (size=150KB). I am trying to get the servlet to display the PDF. I am using IE for this and I am doing this development of Netdynamics. The "File Download" popup comes after 10 minutes or so. When I choose either the "Save As" or "Open..." option, I get a message which says that "IE can't download x.pdf from localhost. Internet Explorer wasn't able to open the website. The requested site is either not available or can't be found. Try again later"
I have attached my code, and I would really appreciate if anyone can give their thoughts on this.
----------------------------------------------
public class HelloWWW2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {


String rpt_name="0";
String str_stage = "0";
HttpSession mySession = request.getSession(true);
//rpt_name = mySession.getValue("sessionRptName").toString();
//String rowNum = mySession.getValue("sessionRptName").toString();
/*************************************************************/
try{
// Load the driver class
Class.forName("com.merant.datadirect.jdbc.sqlserver.SQLServerDriver");
str_stage = "1";
//Create Connection
Connection conn = DriverManager.getConnection
("jdbc:merant:sqlserver://MSSQL14:1433;databaseName=WEBENRLRPT;user=ABC;password=***");
str_stage = "2";
Statement statement=conn.createStatement();

ResultSet reportNames = statement.executeQuery("SELECT rpt_data from reports where rpt_id='2'");
str_stage = "3";

InputStream inStream = null;
while(reportNames.next()){
inStream = reportNames.getBinaryStream("rpt_data");
}
str_stage = "4";

ByteArrayOutputStream outStream = new ByteArrayOutputStream();
int bufSize = 2048, read=0;
byte[] bArray = new byte[bufSize];


//response.setHeader("Content-disposition", "attachment; filename=" + "Example.pdf" );
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
response.setHeader("Content-Disposition" , "attachment; filename=\"MailingLists.pdf\"");
response.setHeader("Content-Description" , "Display database as PDF");

response.setContentType("application/pdf");
response.setContentLength(1000);

while ((read = inStream.read( bArray )) > 0) {
outStream.write( bArray, 0, read );
}

outStream.close();
inStream.close();

}catch(ClassNotFoundException cnfe){
rpt_name = cnfe.toString();
System.out.println("Exception = " + cnfe);
}catch(SQLException e){
rpt_name = e.toString();
System.out.println("Exception = " + e);
}
}
------------------
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12761
    
    5
Why did you do this:
response.setContentLength(1000); //??
in my experience, specialized formats like pdf require an exact content length.
Bill
------------------
author of:
Monty Guppy
Ranch Hand

Joined: Sep 15, 2001
Posts: 49
Originally I wasn't setting any content length but after reading your comments in several posting, I added a length greated than the length of the file I am trying to read.
If you think that that isnot a proper way of handling this, can you make some recommendation. Thanks Bill.
Originally posted by William Brogden:
Why did you do this:
response.setContentLength(1000); //??
in my experience, specialized formats like pdf require an exact content length.
Bill

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15959
    
  19

Bill's right. You don't know how content-length's used by "the" browser - and I use quotes to remind that not everyone in the world is using the same brand and/or version browser. Content-length is a particular problem for Netscape and PDF's, and I can virtually guarantee for the behaviour I've see that a bogus content-length will be as bad or worse (probably crash the browser) than none at all. If you overspecify content-length, the browser if probably going to try to keep sucking data after ther is no more and get upset.
You really should get the true PDF size from the database attributes if you can. If not, copy it to a temp file and use the File.size method.


Customer surveys are for companies who didn't pay proper attention to begin with.
Monty Guppy
Ranch Hand

Joined: Sep 15, 2001
Posts: 49
I finally got it to work. I am doing this in NetDynamics Application Server environment. I realized that I was having most of problems because I was using the following 2 lines of code, suggested by several guys on this forum:
//response.setHeader("Cache-Control","no-cache");
//response.setHeader("Content-Disposition" , "attachment; filename=\"MailingLists.pdf\"");
I also had to make some other changes. Thos interested can look at my code below.
-------------------------------------------
import java.io.*;
import java.lang.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import spider.event.*;
import spider.database.*;
import spider.visual.*;
import spider.html.*;
import spider.*;
import spider.util.*;
import spider.session.*;
import spider.database.CSpCriteriaSQLObject.*;
import com.merant.datadirect.jdbc.sqlserver.SQLServerDriver;
import com.merant.datadirect.*;
public class HelloWWW2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {


String rpt_name="0";
String str_stage = "0", str_file="0";
int fileSize = 0;
HttpSession mySession = request.getSession(true);

try{

// Load the driver class
Class.forName("com.merant.datadirect.jdbc.sqlserver.SQLServerDriver");
str_stage = "1";
//Create Connection
Connection conn = DriverManager.getConnection
("jdbc:merant:sqlserver://MSSQL14:1433;databaseName=***;user=***;password=***");
str_stage = "2";
Statement statement=conn.createStatement();

ResultSet reportNames = statement.executeQuery("SELECT rpt_data from reports where rpt_id='60'");
str_stage = "3";

InputStream inStream = null;

ServletOutputStream outStream = response.getOutputStream();
int bufSize = 2048, read=0;
byte[] bArray = new byte[bufSize];
byte[] fileArray = null;

while(reportNames.next()){
fileArray = reportNames.getBytes("rpt_data");
}
str_stage = "4";

fileSize = fileArray.length;


response.setHeader("Pragma","no-cache");
response.setHeader("Content-Description" , "Display database as PDF");

response.setContentType("application/pdf");
response.setContentLength(fileSize);
outStream.write(fileArray);

outStream.close();
inStream.close();

}catch(ClassNotFoundException cnfe){
rpt_name = cnfe.toString();
System.out.println("ClassNotFoundException = " + cnfe);
}catch(SQLException e){
rpt_name = e.toString();
System.out.println("SQLException = " + e);
}
}
}
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15959
    
  19

If you didn't have the setContentType originally, that would have been a problem. The Content-Disposition header tells WHAT to do with the output (display in browser or download as file), but not what the output IS - which in this case meant "data to be displayed using the Acrobat (pdf) plug-in".
Monty Guppy
Ranch Hand

Joined: Sep 15, 2001
Posts: 49
Tim, I did have the setcontent type earlier. It were the 2 lines above (setHeader) which were causing the trouble.
Originally posted by Tim Holloway:
If you didn't have the setContentType originally, that would have been a problem. The Content-Disposition header tells WHAT to do with the output (display in browser or download as file), but not what the output IS - which in this case meant "data to be displayed using the Acrobat (pdf) plug-in".

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15959
    
  19

OK. If you still have any problems, you might want to check out the MSDN. Microsoft has documented bugs pertaining to Content-Disposition in certain versions of IE.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Serving PDF with my servlet - performance & non-display
 
Similar Threads
file dialog does not close in IE 6
Response as PDF
when streaming doc ciontent to browser, multiple IE File Download prompts displayed
Download file HELP?
Pdf opens blank in browser