fileLength = 0 When trying to Download PDF File from Database - java

fileLength = 0
File Reading Success
getting file Length as null when trying to download pdf file from DATABASE.
Actually have to get Some PDF File which has Some content that was stored in local database
Would You Please Help Me on this Particular ISSue , What should do now to resolve this problem and file was uploaded through Client Side Program Only
public class FileDownload extends HttpServlet {
private static final int BUFFER_SIZE = 40960;
protected void doGet(--){
String bookId = request.getParameter("bookId");
Connection conn=null;
try {
Class.forName("--");
Connection con=DriverManager.getConnection("--");
String sql="SELECT * from book where bookId=?";
PreparedStatement statement = con.prepareStatement(sql);
statement.setString(1, bookId);
ResultSet result = statement.executeQuery();
if(result.next()) {
String bookTitle = result.getString("bookTitle");
Blob blob = result.getBlob("bookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("fileLength = " +fileLength);
ServletContext context = getServletContext();
String mimeType = context.getMimeType(bookTitle);
if (mimeType == null) {
mimeType = "application/pdf";
}
System.out.println("File Reading Success");
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; fileName=\"%s\"", bookTitle +".pdf");
response.setHeader(headerKey, headerValue);
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1){
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
}

InputStream.available() does not return the file length, but rather the number of bytes which can be read from the stream without blocking. Most likely the database does not send any bytes of the Blob until you explicitly request the content, and so 0 is returned.
Therefore use
int fileLength = blob.length();
which gives you the exact length of the file.

Related

Prevent downloaded files from replacing or overwriting each other

How to download all file types in MySQL database using Java app and prevent one file from replacing the other?
How can I include all file types in my filepath=("D:\\sch work\\skirt\\filename.pdf"); so that I am able to download pdf, docx, jpeg etc, from a MySQL database using Java mouse click event on a JTable?
I have two problems.
I can only open a PDF files although I want to open docs, JPEG and img files.
Every time I download another file from a different row it replaces the existing one. I would like to keep all of them
Below please find my code for mouse click event and please suggest what I should add for it to work as I need it.
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
String filePath =("D:\\sch work\\skirt\\filename.pdf");
int BUFFER_SIZE = 4096;
try {
int cert_code= jTable1.getSelectedRow();
String tableClick=(jTable1.getModel().getValueAt(cert_code,3).toString());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee_certificate","root","");
String sql= "SELECT cert FROM certificate WHERE cert_code =?" ;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, tableClick);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
Blob blob = rs.getBlob("cert");
InputStream inputStream = blob.getBinaryStream();
OutputStream outputStream = new FileOutputStream(filePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//JOptionPane.showMessageDialog(null,"file saved")
} }
catch (Exception e)
{JOptionPane.showMessageDialog(null,e);}
}
If you want something other than PDF, you should store what's in that cert blob, so you can send out the appropriate filename/type:
You get PDF because that's the exact+only file type you write out to:
String filePath =("D:\\sch work\\skirt\\filename.pdf");
^^^
Perhaps something more like (in pseudo-code):
select cert,filename,filetype from ...
filepath = 'd:\sch work\skirt' + filename
header('Content-type: ' + filetype);
here is my answer.God bless Marc B abundantly.
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
int BUFFER_SIZE = 4096;
try {
int cert_code= jTable1.getSelectedRow();
String tableClick=(jTable1.getModel().getValueAt(cert_code,3).toString());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee_certificate","root","");
String sql= "SELECT cert, cert_name FROM certificate WHERE cert_code =?" ;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, tableClick);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
String filename = rs.getString("cert_name");
Blob blob = rs.getBlob("cert");
InputStream inputStream = blob.getBinaryStream();
String filePath ="D:\\sch work\\skirt\\"+filename;
OutputStream outputStream = new FileOutputStream(filePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
//JOptionPane.showMessageDialog(null,"file saved")
} }
catch (Exception e)
{JOptionPane.showMessageDialog(null,e);}
}

How to read a href parameter in servlet?

on address bar : http://localhost:8080/tryupload/downloadservlet?bookid=15bk
bookid=15bk (15bk was i got from my bookId on database, by getString on servlet)
then , below is my display on servlet (not jsp)
out.println("<TD>Download</TD>");
then it goes to
downloadservlet.java // but it didnt worked. Blank page.
How read the "boookid " from this link http://localhost:8080/tryupload/downloadservlet?bookid=15bk to my servlet? and be execute on my downloadservlet.java?
downloadservlet.java
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String bookId = request.getParameter("bookId");
Connection conn = null; // connection to the database
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
// queries the database
String sql = "SELECT * FROM books WHERE bookId = ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, bookId);
ResultSet result = statement.executeQuery();
if (result.next()) {
// gets file name and file blob data
String fileName = result.getString("BookContent");
Blob blob = result.getBlob("BookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("fileLength = " + fileLength);
ServletContext context = getServletContext();
// sets MIME type for the file download
String mimeType = context.getMimeType(fileName);
if (mimeType == null) {
mimeType = "application/octet-stream";
}
// set content properties and header attributes for the response
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", fileName);
response.setHeader(headerKey, headerValue);
// writes the file to the client
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
} else {
// no file found
response.getWriter().print("File not found for the id: " + bookId);
}
} catch (SQLException ex) {
ex.printStackTrace();
response.getWriter().print("SQL Error: " + ex.getMessage());
} catch (IOException ex) {
ex.printStackTrace();
response.getWriter().print("IO Error: " + ex.getMessage());
} finally {
if (conn != null) {
// closes the database connection
try {
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
}
you read the parameter correctly with
request.getParameter("bookid")
However you cannot apply directly Integer.parseInt as you read 15bk and which is not an integer, if you need 15 out of 15 bk you need an additional step of parsing.
Following your last edit, its the same issue - you cannot do
statement.setInt(1, bookid);
bookid will not be an int. you need to parse, not sure but for example if you want to eliminate the last 2 characters you could do
bookIntId = bookId.substrings(0, bookId.length - 2)
String bookId = request.getParameter("bookid");
If your parameter value is 15bk then your line of code:
int bookid = Integer.parseInt(request.getParameter("bookid"));
Will throw NumberFormatException as bk cannot be converted into an integer value.

How to set encoding to file for download

I have a method which start download of text file that is stored in oracle.
The column type is BLOB. I'm using this code below to init download, but I have no idea how set encode to this file when client downloaded it.
if (result.next()) {
String fileName0 = String.valueOf(result.getDate(columnData));
String fileName1 = String.valueOf(result.getInt(columnNumSolit));
String fileName2 = String.valueOf(result.getInt(columnNumComplto));
BLOB blob = ((OracleResultSet) result).getBLOB(columnFile);
InputStream inputStream = blob.getBinaryStream();
//int fileLength = inputStream.available();
int fileLength = blob.getChunkSize();
ServletContext context = getServlet().getServletContext();
// Set MIME to file.
String mimeType = context.getMimeType(fileName0+fileName1+fileName2+ext);
if (mimeType == null) {
mimeType = "application/octet-stream";
}
// header to response.
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",fileName0+fileName1+fileName2+ext);
response.setHeader(headerKey, headerValue);
// write file to client.
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[fileLength];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
tipoSolit = null;
}else {
//do something
}
What behavior are you trying to get the browser to do? Are you sending a video or mp3 or what? The mimetype is set by the headers you send before the file. If know of a website that has the behavior you are looking for, you can simply view what headers they send in chrome or in wireshark and then just use those in your own code.
One of the problems with file-type encoding is that you need to keep the encoding correct for each step that the bytes take. This means that if any step in the "upload->storage in db->fetching db->download" removes utf-8 encoding, you get the wrong answer. I wrote a post about my travels with UTF-8 and MySQL here: https://stackoverflow.com/a/14411280/836450 I would suggest sending a file that has a single utf-8 character, and then debugging the entire chain by hand.

How to download file using JavaScript/ExtJs?

In jsp i get file from BD and want to download it on client:
<%
String num = request.getParameter("param");
Statement sta = null;
sta = conn.createStatement();
String fileName="";
String sql=("SELECT files,filename FROM filestock WHERE num =(SELECT filestock_id FROM parcels_temp WHERE num="+num+")");
ResultSet rs=sta.executeQuery(sql);
while(rs.next()){
byte[] file = rs.getBytes("files");
fileName=rs.getString("filename");
}
FileOutputStream fs = new FileOutputStream(new File(fileName));
BufferedOutputStream bs = new BufferedOutputStream(fs);
bs.write(file);
bs.close();
fs.close();
rs.close();
ps.close();
%>
I will PDF file. So i have some questions:
1. What i gonna do with file to send it to JavaScript.
2. Can i save this file using ExtJs 3.4 or JavaScript?
UPDATE
Now i try to send file from server to client:
<%
String num = request.getParameter("param");
Statement sta = null;
sta = conn.createStatement();
String fileName="";
byte[] file=null;
int bufferSize = 8192;
String sql=("SELECT files,filename FROM filestock WHERE num =(SELECT filestock_id FROM parcels_temp WHERE num="+num+")");
ResultSet rs=sta.executeQuery(sql);
while(rs.next()){
file = rs.getBytes("files");
fileName=rs.getString("filename");
}
File dFile=new File(fileName);
InputStream in1 = request.getInputStream();
int read;
while ((read = in1.read(file, 0, bufferSize)) != -1) {
out.write(file, 0, read);
}
sta.close();
rs.close();
conn.close();
%>
But get error:
The method write(char[], int, int) in the type Writer is not applicable for the arguments (byte[], int, int)
So how to do it?
UPDATE2
Using this code i dont get any errors but in firebug i see that server nothing send to client:
<%
String num = request.getParameter("param");
Statement sta = null;
sta = conn.createStatement();
String fileName="";
byte[] file=null;
int bufferSize = 8192;
String sql=("SELECT files,filename FROM filestock WHERE num =(SELECT filestock_id FROM parcels_temp WHERE num="+num+")");
ResultSet rs=sta.executeQuery(sql);
while(rs.next()){
file = rs.getBytes("files");
fileName=rs.getString("filename");
}
//File dFile=new File(fileName);
FileOutputStream fout = fout = new FileOutputStream(fileName);
//BufferedInputStream in1 = new BufferedInputStream(fout);
InputStream in1 = request.getInputStream();
int read;
while ((read = in1.read(file, 0, bufferSize)) != -1) {
fout.write(file, 0, read);
}
sta.close();
rs.close();
conn.close();
%>
You have simply to create a Download URL with a Content-Disposition Header.
Now the bad/good news (It depends on the point of view). You can not store a file through JavaScript onto a users-filesystem (expect the new File-API). But this will sandbox your filesystem. So you can't make the browser store that file onto a certain path.

How to get a binary file from a remote php script response?

I'm calling a script that gives me a binary file (12345.cl), with binary data. The script is done, and it's working, if I paste it on the navigator I get the binary file.
Now I have a problem: How I transform the response of the script into a binary resource to use it in my app?
For the moment, i have this code:
public void decodeStream( String mURL ){
BufferedInputStream bis = new BufferedInputStream(new URL(mURL).openStream(), BUFFER_IO_SIZE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos, BUFFER_IO_SIZE);
copy(bis, bos);
bos.flush();
Then, I have a BufferedOutputStream with the response, but I don't know how to transform it into a binary resource to use it
I need to obtain a datainputstream with the file but I don't know how to achieve it
You can use following code:
public void decodeStream( String mURL, String ofile ) throws Exception {
InputStream in = null;
FileOutputStream out = null;
try {
URL url = new URL(mURL);
URLConnection urlConn = url.openConnection();
in = urlConn.getInputStream();
out = new FileOutputStream(ofile);
int c;
byte[] b = new byte[1024];
while ((c = in.read(b)) != -1)
out.write(b, 0, c);
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}

Categories

Resources