PDF file corrupted after downloading from mysql java - java

I am trying to upload a pdf file to my database and trying to download same file but I am unable to open the file after it's downloaded I get an error stating file type not supported.
Here is the code for file Upload.
package itext;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import com.mysql.jdbc.PreparedStatement;
public class FileUpload {
public static void fileupload() throws FileNotFoundException{
String inFile="D:/Eclipse Java/myown.pdf";
FileInputStream io = new FileInputStream(inFile);
byte[] pdfData = new byte[(int) inFile.length()];
DataInputStream dis;
try {
dis = new DataInputStream(new FileInputStream(inFile));
dis.readFully(pdfData); // read from file into byte[] array
dis.close();
Connection dbConnection;
String myConnectionString =
"jdbc:mysql://******/*****";
dbConnection = DriverManager.getConnection(myConnectionString, "****", "****");
PreparedStatement ps = (PreparedStatement) dbConnection.prepareStatement("INSERT INTO Form_BL (AppID,Form) VALUES (?,?)");
ps.setString(1, "1");
ps.setBytes(2, pdfData); // byte[] array
ps.executeUpdate();
ps.setBinaryStream(1, (InputStream)dis,(int)inFile.length());
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And this is the code for downloading
package itext;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import com.mysql.jdbc.Blob;
import com.mysql.jdbc.PreparedStatement;
public class FileDownload {
public static void filedownload(){
Connection dbConnection;
ResultSet rs;
String myConnectionString =
"jdbc:mysql://*****/*****";
try {
dbConnection = DriverManager.getConnection(myConnectionString, "****", "****");
PreparedStatement ps=(PreparedStatement) dbConnection.prepareStatement("select AppID from Form_BL where AppID='1' ");
rs=ps.executeQuery();
rs.next();
java.sql.Blob b=rs.getBlob(1);
byte barr[]=new byte[(int)b.length()];//an array is created but contains no data
barr=b.getBytes(1,(int)b.length());
FileOutputStream fout=new FileOutputStream("D:/download.pdf");
fout.write(barr);
fout.close();
System.out.println("ok");
dbConnection.close();
ps.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
I was using the reference of the following link for this operation.
Upload PDF file to mysql BLOB by using java.sql.PreparedStatement without corruption. Thanks in advance

It looks like the code to save the binary content (PDF file) into a BLOB is fine. But when you try to get the PDF content back it looks like you have some trouble.
You might wan to try this:
Blob b = rs.getBlob(1);
InputStream is = b.getBinaryStream();
FileOutputStream fos = new FileOutputStream("D:/download.pdf");
int i = 0;
// IMPORTANT: Remember to handle/close all I/O properly
while ((i = is.read()) != -1) {
fos.write(b);
}

Related

Want to compress jpeg using blob with image as in and out parameter

i want to compress a jpeg Image, running a java program from an pl/sql procedure within th oracle database.
I want to call the java class from pl/sql procedure with the blob (jpeg image), an the java program should return the compresses image in a blob.
I have found this code from https://examples.javacodegeeks.com/desktop-java/imageio/compress-a-jpeg-file/ an it works fine and the jpeg images are compressed. But this program used jpeg-Files in the file system, i need the original image and the compresse image as blob parameter
I have used this program and have modified it to do what I need it to do.
To test my program, I get a jpg image from my database as blob via odbc an then call compressJPEG (myBlobCopy) with the blob. To show what happend, i do some output in the classes. The size of the blob before an after calling the compressJPEG is the same.
Here the output:
126 23190 myimage.jpg Length of retrieved Blob: 4284416
Length of copy Blob: 4284416
Call compressJPEG (myBlobCopy)
now in compressJPEG
Back from compressJPEG: Length of retrieved Blob: 4284416
Here the class. It seems, that the compressed image (blob) is not returned. Please can you help me!!!!!!
import java.sql.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.sql.Blob;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
//import java.sql.SQLException;
class OracleConCompressBLOB{
public static void main(String args[]){
try{
//step1 load the driver class
Blob myBlob = null;
Blob myBlobCopy = null;
Class.forName("oracle.jdbc.driver.OracleDriver");
String dbURL = "jdbc:oracle:thin:#(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = xxxx)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = xxxx) ) )";
String strUserID = "xxxx";
String strPassword = "xxxxx";
//step2 create the connection object
Connection con=DriverManager.getConnection(dbURL,strUserID,strPassword);
//step3 create the statement object
Statement stmt=con.createStatement();
//step4 execute query
// fuer pbent ResultSet rs=stmt.executeQuery("select PRFO_ID, PRFO_PRAX_ID , PRFO_DATEINAME, PRFO_FOTO from T_PRAFOTO where PRFO_ID = 17");
ResultSet rs=stmt.executeQuery("select PRFO_ID, PRFO_PRAX_ID , PRFO_DATEINAME, PRFO_FOTO from T_PRAFOTO where PRFO_ID = 166 FOR UPDATE");
if (rs.next()) {
myBlob = rs.getBlob(4);
myBlobCopy = myBlob;
System.out.println(rs.getInt(1)+" "+rs.getInt(2)+" "+rs.getString(3)+" Length of retrieved Blob: " + myBlob.length());
System.out.println(" Length of copy Blob: " + myBlobCopy.length());
System.out.println("Call compressJPEG (myBlobCopy) ");
compressJPEG (myBlobCopy) ;
System.out.println("back from compressJPEG: Length of retrieved Blob: " + myBlobCopy.length());
}
//step5 close the connection object
con.close();
}catch(Exception e){ System.out.println(e);}
}
public static void compressJPEG(Blob blob) throws IOException {
// File imageFile = new File("myimage.jpg");
// File compressedImageFile = new File("myimage_compressed.jpg");
// InputStream is = new FileInputStream(imageFile);
// OutputStream os = new FileOutputStream(compressed ImageFile);
System.out.println("now in compressJPEG");
BufferedImage bufferedImage = null;
OutputStream outputStream = null;
float quality = 0.5f;
try {
// create a BufferedImage as the result of decoding the supplied InputStream
// BufferedImage image = ImageIO.read(is);
bufferedImage = ImageIO.read(blob.getBinaryStream());
outputStream = blob.setBinaryStream(0);
// test
// get all image writers for JPG format
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
if (!writers.hasNext())
throw new IllegalStateException("No writers found");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
// compress to a given quality
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
// appends a complete image stream containing a single image and
//associated stream and image metadata and thumbnails to the output
writer.write(null, new IIOImage(bufferedImage, null, null), param);
// close all streams
// is.close();
// os.close();
// ios.close();
// writer.dispose();
outputStream.flush();
ios.close();
outputStream.close();
writer.dispose();
} catch (IOException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
catch(IllegalArgumentException e) {
e.printStackTrace();
}
}
}

Is there a way to read PDF file stream with out using byte[ ] or readAllBytes() using java 1.8

My requirement is to invoke a Rest api, the o/p of which is a pdf file & generate a PDF file using a scripting language which is based on java.
We are using readAllBytes() method in our scripts, as we cannot use byte[] in our scripts(restriction). Equivalent java code for our script is below. As using readAllBytes() method is not recommended for reading large streams, is there an alternative for this without using byte[]? .
Please note: We are using 1.8 java and cannot use any third party libraries except Apache Commons IO.
Thank you for your help.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class ExecuteReportFromScript {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
byte[] buffer = new byte[1024];
URL url = new URL("restEndPoint");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Cookie", "myCookieData");
con.setRequestProperty("Accept", "application/json");
con.setDoOutput(true);
con.connect();
System.out.println("Response Code:" + con.getResponseCode());
InputStream ip = con.getInputStream();
BufferedInputStream is = new BufferedInputStream(ip);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write( is.readAllBytes());
/*
* int length; while ((length = is.read(buffer)) > -1 ) { bos.write(buffer, 0,
* length); }
*/
bos.flush();
File file = new File("PathToFile\\FileName.pdf");
try(BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(file))){
salida.write(bos.toByteArray());
salida.flush();
}
ip.close();
is.close();
bos.close();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Write the stream directly to a file using Files.copy(InputStream in, Path target, CopyOption... options) (since Java 7).
Path file = Paths.get("PathToFile\\FileName.pdf");
try (InputStream in = new BufferedInputStream(con.getInputStream())) {
Files.copy(in, file);
}

How to retrieve an zip file from oracle blob using java?

I have an zip file stored in an Oracle database table which is consisting of three different xml files. What I'm trying to do is get this zip file in my local file system. To retrieve this zip file I have written below java code:
package com.pack.IOT;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test2 {
public static Connection con;
public static PreparedStatement stmt;
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(url,uname,pwd);
stmt=con.prepareStatement("select * from FileStore");
ResultSet rs=stmt.executeQuery();
while (rs.next()) {
InputStream is = rs.getBinaryStream(3);
convert(is);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
private static void convert(InputStream is) {
FileOutputStream outputStream = null;
File file = new File("C:\\Users\\nshaik\\Desktop\\IOTZip.zip");
try {
outputStream = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result;
result = bis.read();
while (result != -1) {
buf.write((byte) result);
result = bis.read();
}
outputStream.write(buf.toByteArray());
System.out.println("File write success....");
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
outputStream.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
The code is running fine, but I'm seeing an error "Unexpected end of archive", and this zip file should contain three different files, but I see only one file and it has a size of zero.
I'm not sure what I'm doing wrong, anyone's help would be really appreciated.
Below is the working code for above requirement,
package com.pack.IOT;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test2 {
public static Connection con;
public static PreparedStatement stmt;
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(url,uname,pwd);
stmt=con.prepareStatement("select * from FileStore");
ResultSet rs=stmt.executeQuery();
while (rs.next()) {
InputStream is = rs.getBinaryStream(3);
convert(is);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
private static void convert(InputStream is) {
FileOutputStream outputStream = null;
File file = new File("C:\\Users\\nshaik\\Desktop\\IOTZip.zip");
try {
outputStream = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result;
result = bis.read();
while (result != -1) {
buf.write((byte) result);
result = bis.read();
}
outputStream.write(buf.toByteArray());
System.out.println("File write success....");
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
outputStream.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}

Download blob data in a zip file in a simple java program

I'm not able to download the files using the below code as i have multiple types of extensions to download and i want to zip all the files and download. If i run the below code, it says files is corrupted. someone please help on this?
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JdbcReadFile {
private static final int BUFFER_SIZE = 4096;
public static void main(String[] args) {
String url = "jdbc:oracle:thin:#xxx:xxxx:xxx";
String user = "xxx";
String password = "xxx";
String filePath = "C:/abc.vsd";
try {
Connection conn = DriverManager.getConnection(url, user, password);
String sql = "SELECT DOC_BO FROM table fetch first 10 rows only";
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet result = statement.executeQuery();
if (result.next()) {
Blob blob = result.getBlob("DOC_BO");
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();
System.out.println("File saved");
}
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
No front end is required for this. Issue is resolved using the below code.
public class BlobDataExtract {
static ZipOutputStream zos = null;
static String url = "jdbc:oracle:thin:#hostname:1521:SID";
public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(url, "user", "password");
String sql = "select Blob_Data,ORIG_NM from table";
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
byte[] docBlob = null;
String filename = null;
FileOutputStream fos = new FileOutputStream("C:/Users/test.zip");
zos = new ZipOutputStream(fos);
while (rs.next()) {
docBlob = rs.getBytes("Blob_Data");
filename = rs.getString("ORIG_NM");
try {
zos.putNextEntry(new ZipEntry(filename));
zos.write(docBlob, 0, docBlob.length);
} catch (FileNotFoundException ex) {
System.err.println("A file does not exist: " + ex);
} catch (IOException ex) {
System.err.println("I/O error: " + ex);
}
zos.closeEntry();
}
}
}

How to download a pdf file from oracle database using servlets without corrupting the file?

I have a servlet in which I retrieve a pdf file from oracle database based on id and write it into the response stream. But when I try to do that, the downloaded file is corrupted and has zero file size. Adobe reader gives an error saying that "Adobe could not open "myfile.pdf" because it is either not a supported type...".
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#MultipartConfig( fileSizeThreshold = 1024 * 1024,
maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5)
public class DBFileDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// size of byte buffer to send file
private static final int BUFFER_SIZE = 4096;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// get file id from URL's parameters
String course_code = request.getParameter("course_code");
Connection conn = null; // connection to the database
try {
// connects to the database
Connection con = JDBCfile.getOracleConnection();
// queries the database
String sql = "SELECT * FROM course_syllabus WHERE course_code = ?";
PreparedStatement statement = con.prepareStatement(sql);
statement.setString(1, course_code);
ResultSet result = statement.executeQuery();
if (result.next()) {
// gets file name and file blob data
String fileName = result.getString("file_name");
Blob blob = result.getBlob("syllabus_file");
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 file id: " + course_code);
}
}catch (SQLException ex) {
ex.printStackTrace();
response.getWriter().print("SQL Error: " + ex.getMessage());
} catch (IOException ex) {
ex.printStackTrace();
response.getWriter().print("IO Error: " + ex.getMessage());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCfile.cleanup(con,statement); //closes connection
}
}
}
course_syllabus table has columns: course_code varchar,file_name varchar,syllabus_file (blob)
everything executes perfectly but the file I download has zero byte and nothing to read. I am new to servlet programming, Anybody having any clue?
Please post a working solution too. Thanks in advance.
One problem is here:
int fileLength = inputStream.available();
available() does not return the total number of bytes in the stream. It just returns how many bytes can be read without blocking. From the documentation:
Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.
Use Blob.length() instead:
long fileLength = blob.length();
// ...
response.setContentLengthLong(fileLength);
Another problem is your error handling. Do not act like the method succeeded if it did not succeed. You want the HTTP call to return an error, if your method could not successfully obtain the file.
First, remove the catch (IOException ex) block. If there is an IOException, you want it to propagate, so the HTTP call will fail as it should.
The other two blocks need to propagate their errors:
} catch (SQLException ex) {
throw new ServletException(ex);
} catch (ClassNotFoundException e) {
throw new ServletException(e);
Similarly, you want to do more than just print "File not found" when the ResultSet is empty. There is an HTTP response code intended specifically to indicate that an HTTP request failed because the requested resource was not found:
if (result.next()) {
// ...
} else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().print("File not found for the file id: " + course_code);
}

Categories

Resources