Win a copy of Learn Spring Security (video course) this week in the Spring forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Serving PDF with my servlet - performance & non-display

 
Monty Guppy
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 13055
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 17989
47
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Monty Guppy
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 17989
47
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 17989
47
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic