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);}
}
Related
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.
my mission is to change 2 php pages with a java webapp that writes an upload pdf file to a clob and reads it when user ask for a download.
I threated the pdf as a byte array and have been able to read/write it correctly
the big problem is the backward compatibility: files written by php are not readable by my java webapp and vice-versa
thanks in advance for help
NOTE: Do not answer me to use a Blob, I know it is the easy way but in this case we have to assume we cannot make an alter table on the db due to backward compatibility
Here's my code to read the clob into a byte array:
byte[] result = null;
InputStream is = null;
ByteArrayOutputStream bos = null;
//...prepare the query to get clob as first column in the resultset
ResultSet rs = stmt.executeQuery();
int len;
int size = 1024;
byte[] buf;
if(rs.next()) {
is = rs.getBinaryStream(1);
bos = new ByteArrayOutputStream();
buf = new byte[size];
while ((len = is.read(buf, 0, size)) != -1)
bos.write(buf, 0, len);
bos.flush();
bos.close();
is.close();
result = bos.toByteArray();
}
rs.close();
here's the code to write the byte array into clob:
//...some other sql stuff here...
stmt = conn.prepareStatement("SELECT clob_col FROM my_table WHERE prim_key = ? FOR UPDATE");
stmt.setString(1, param);
ResultSet rs = stmt.executeQuery();
Clob myclob=null;
if(rs.next())
myclob=rs.getClob(1);
OutputStream writer = myclob.setAsciiStream(1L);
writer.write(allegato);
writer.flush();
writer.close();
stmt = conn.prepareStatement("UPDATE my_table SET clob_col = ? WHERE prim_key = ? ");
stmt.setClob(1, myclob);
stmt.setString(2, param);
stmt.executeUpdate();
oracle encoding is ITALIAN_ITALY.WE8ISO8859P1
php encoding is ITALIAN_ITALY.UTF8
A possible solution:
write to clob the hex rapresentation of the byte array, and do the same in read phase
the main advantage are
- few changes in php and java
- no changes to db (alter table)
- indipendent from db encoding
in php we use bin2hex and hex2bin functions before to write and after read the clob
in java we implement 2 easy equivalent functions of bin2hex and hex2bin:
public static byte[] HexToBin(String str){
try{
byte[] result=new byte[str.length()/2];
for (int i = 0; i < result.length; i++)
result[i]=(byte) Integer.parseInt(str.substring(2*i, (2*i)+2), 16);
return result;
}catch(Exception x){
x.printStackTrace();
return null;
}
}
public static String BinToHex(byte[] b){
try{
StringBuffer sb=new StringBuffer();
for (byte bb:b) {
String hexStr = String.format("%02x", bb);
sb.append((hexStr.length()<2)?"0":"");
sb.append(hexStr);
}
return sb.toString();
}catch(Exception x){
x.printStackTrace();
return null;
}
}
I am reading the blob data from Oracle database & writing it to a text file. I have two column in my database called Number & system. I have 100 counts in my table. But only the last row is writing in my text row. below is the code I have tried.
rs =stmt.executeQuery("select Number, system from system");
Blob lob = null;
while (rs.next()) {
String RECID = rs.getString(1);
System.out.println("Number"+ Number);
lob=rs.getBlob("system");
byte[] bdata = lob.getBytes(1, (int) lob.length());
String text = new String(bdata);
System.out.println("text"+ text);
System.out.println("rs value"+ lob);
String test=null;
test=RECID+":"+text;
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeBytes(test);
dos.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
In text file i am getting 100th record only other 99 rows are not writing.
You are replacing existing text each time in your while loop.
Try this:
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
DataOutputStream dos = new DataOutputStream(fos);
while (rs.next()) {
String RECID = rs.getString(1);
System.out.println("Number"+ Number);
lob=rs.getBlob("system");
byte[] bdata = lob.getBytes(1, (int) lob.length());
String text = new String(bdata);
System.out.println("text"+ text);
System.out.println("rs value"+ lob);
String test=null;
test=RECID+":"+text;
dos.writeBytes(test+"\n");
}
dos.close();
Replace the line in your code
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
With:
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt", true);
I am trying to save images in MySQL database from a Java swing application. I am using JFileChsoser to get the path of the image. Then after that converting the file so that it can be saved in the MySQL column which is of BLOB type. But every image I try to save does not save properly or get converted properly. Could someone tell me what I'm doing wrong over here?
private void btn_choosepicActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser picchooser = new JFileChooser();
picchooser.setDialogTitle("Select Image");
picchooser.showOpenDialog(null);
File pic=picchooser.getSelectedFile();
path= pic.getAbsolutePath();
txt_path.setText(path.replace('\\','/'));
try{
File image = new File(path);
FileInputStream fis = new FileInputStream(image);
ByteArrayOutputStream baos= new ByteArrayOutputStream();
byte[] buff = new byte[1024];
for(int readNum; (readNum=fis.read(buff)) !=-1 ; ){
baos.write(buff,0,readNum);
}
userimage=baos.toByteArray();
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
And then after this Im saving it to the database like so.
private void btn_saveActionPerformed(java.awt.event.ActionEvent evt) {
String user= txt_username.getText();
try{
String sql="insert into imgtst (username,image) values ('"+user+"','"+userimage+"')";
pst=con.prepareStatement(sql);
pst.executeUpdate();
JOptionPane.showMessageDialog(null, "Saved");
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
and I have declared the variable userimage and path as a global variables
String path=null;
byte[] userimage=null;
You are converting the byte[] to a String in your sql statement, and you will end up with incorrect data.
The right way to use a BLOB would be to pass the InputStream itself. You can use the FileInputStream you are using to read the file.
File image = new File(path);
FileInputStream fis = new FileInputStream ( image );
String sql="insert into imgtst (username,image) values (?, ?)";
pst=con.prepareStatement(sql);
pst.setString(1, user);
pst.setBinaryStream (2, fis, (int) file.length() );
When you retrieve it back you can similarly get an InputStream from the ResultSet:
InputStream imgStream = resultSet.getBinaryStream(2);
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.