I am writing a web app that I would like to be able to import a csv file into a database from a jsp. Previously I have used the following code to insert the csv into the database.
LOAD DATA LOCAL INFILE "/myFileLocation.csv"
INTO TABLE myTable
COLUMNS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;
Which works great when I have the file locally.
My question, when I upload the csv file in my jsp as a multipart. Is it possible for me to pass that PartItem file as a variable and replace the "/myFileLocation.csv" with the PartItem files temp location?
I can see the temp location when I debug and view the PartItem file which resides in repository/path under the variables table. Is this at all possible to access or do i need to parse the csv and insert it into the database that way?
I ended up finding a way to make this work. Not sure if it's the best solution but its working as I envisioned. Basically I create a string pointing to an assets folder I created in the web/resources like this.
final String mainPath = this.getServletContext().getRealPath("resources/assets");
Then I read the uploaded file, check to see if the file already exists in my assets folder, if it does I delete it.
Part filePart = request.getPart("csvFile");
String path = mainPath + "/" + filePart.getSubmittedFileName();
File fileTemp = new File(path);
if(fileTemp.exists()){
fileTemp.delete();
}
Lastly I read the uploaded file and write a new file in the location I directed it to which in this case is the assets folder I created like this.
final String fileName = filePart.getSubmittedFileName();
File convFile = new File(filePart.getSubmittedFileName());
FileOutputStream fos = new FileOutputStream(convFile);
OutputStream out = null;
InputStream filecontent= null;
try{
out = new FileOutputStream(new File(mainPath + File.separator + fileName));
filecontent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while((read = filecontent.read(bytes)) != -1){
out.write(bytes, 0, read);
}
} catch (FileNotFoundException fne) {
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
}
After that I just passed a string containing the path to the file with the file name to the DAO I created where I was able to utilize the sql statement I had posted above.
Like I stated before, not sure if this is the best way to do this but it seems to be working fine for me and none of my java code is contained within my jsp. If anyone has a better way of doing this or sees something wrong with what I did here let me know, I'd be very interested to hear about it.
Related
I am trying to send Files in fragments using DatagramPackets in Java (part of an assignemt.) When I am trying to save the incoming File I get access denied error, but I believe that it is not a permissions issue.
Here is the brunt of it:
I let the user sending the file to choose it using FileChooser. And create a new Message object.
//....
File f = content.showFileChooser();
byte type = Byte.parseByte("4");
Message m;
try {
if (mode == 1){
m = new Message(f, content.getServerData().getFragmentSize(), (short) (sentMessages.size()+1), type);
serverThread.send(m);
}
//...
During Message creation the file gets split up into byte arrays, where the size of each array is predetermined by the user. The code is quite lengthy so I am not going to post the chopping process, but this is how I convert the File object into a big byte[] which then gets chopped up
Path p = Paths.get(file.getAbsolutePath());
this.rawData = Files.readAllBytes(p);
After the Message is created and chopped up into byte arrays I send them using DatagramPackets. The other side then uses those to create a new Message object. Once all fragments arrive rawData is extracted from the Message object again. The problem believe lies here:
Message m = receivedMessages.get(msgIndex-1);
byte[] fileData = m.getFile();
if (fileData != null){
System.out.println("All file fragments received.");
content.append("Received a file in" + m.getFragmentCount()+" fragments. Choose directory. " ,1);
//I BELIEVE THIS TO BE THE CRITICAL POINT
String filePath = content.chooseDirectory();
if (filePath == null)
return;
FileOutputStream fos;
try {
fos = new FileOutputStream(filePath);
fos.write(fileData);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Once all fragments arrive I let the user select a directory using FileChooser with DIRECTORY_ONLY choice mode. As I understand, FileOutputStream requires a full path for the new File. Do I have to send the file name and extension separately or can it be extracted from the received File data?
You are writing directory path to filePath, then try to open that directory with FileOutputStream. No wonder that doesn't work, you have to specify the filename too.
String filename = "myfile.txt"; //Or receive and set this some other way
File outFile = new File(filePath, filename);
fos = new FileOutputStream(outFile);
I don't see you sending/receiving the filename anywhere, though. You'll need to either make it constant or transfer it along with file contents.
I'm making a fairly basic site for my mother, and seeing as I did some stuff in Java EE and with EJB during college last semester, I'm going to stick to this.
The only issue I am having is uploading images - I can't seem to find any examples.
I'm using entity classes and parameterised queries. This is the code for writing to the database, which is working fine, I'm just setting the blob image value to null for the moment.
#Override
public void addClothes(String designer, String cname, String ctype, String desc) {
Clothes c = new Clothes();
em.persist(c);
c.setDesigner(designer);
c.setCname(cname);
c.setCtype(ctype);
c.setDescript(desc);
c.setImage(null);
}
I have a servlet that takes a file, I'm just not sure how the file, when passed, should be sorted and what I should write to the database (from what I'm seeing, it's byte[])
A hand in the right direction would be appreciated!
Once you have the file on the server, either in memory or in a local or temp file (that depends on the framework or libraries that you're using), you will have a reference of a wrapper type.
If you are using Apache Commons File Upload, you have a FileItem reference. For request all contents of the file as byte array:
byte[] contents = fileItem.get();
If you are using Tomahawk of Trinidad, you have a org.apache.myfaces.trinidad.model.UploadedFile reference. For request all contents of the file as byte array, you can use class IOUtils of the Apache Commons IO:
byte[] contents = IOUtils.toByteArray(uploadedFile.getInputStream());
Of if you have a reference of org.apache.myfaces.custom.fileupload.UploadedFile, is more simple:
byte[] contents = uploadedFile.getBytes();
UPDATE
If you are using Java EE 6, you can use new features of Server 3.0 specification for upload files without extra libraries. See the excellent tutorial of BalusC in The BalusC Code: Uploading files in Servlet 3.0
To work with hibernatehttp://www.mkyong.com/hibernate/hibernate-save-image-into-database/
To work with JDBC:
To Write image into database BLOB using Jdbc , You need to Convert the File into Inputstream. statement.setBinaryStream(2, (InputStream) inputStream,(int) (image.length())); PreparedStatement statement offer method setBinaryStream() which is used to write binary stream into database BLOB column.
Here is a code snippet to help you:
File image = new File("C:/test.jpg");
inputStream = new FileInputStream(image);
Prepared statement = //define as per your table
// set the file binary stream
statement.setBinaryStream(2, (InputStream) inputStream,(int) (image.length()));
statement.executeUpdate();
In your Clothes class, you can add:
#Lob
private byte[] image;
// Getter/Setter methods
Got it working ! Somewhat, with this code:
public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
out = response.getWriter();
final String path = "clothesImages" + File.separator + request.getParameter("designer") + File.separator + request.getParameter("ctype") + File.separator + request.getParameter("cname");
out.println(path);
String currentDir = new File(".").getAbsolutePath();
out.println(currentDir);
final Part filePart = request.getPart("image");
final String filename = "image.jpg";
File file = new File(path);
if (!file.exists()){
out.println("Dir Doesn't Exist");
file.mkdirs();
}
OutputStream outstream = null;
InputStream filestream = null;
try{
outstream = new FileOutputStream(new File(path + File.separator + filename));
filestream = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while(( read = filestream.read(bytes)) != -1){
outstream.write(bytes, 0, read);
}
out.println("New file " + filename + " created at " + path);
}catch (FileNotFoundException fne) {
out.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent "
+ "location.");
out.println("<br/> ERROR: " + fne.getMessage());
}finally {
if (out != null) {
out.close();
}
if (filestream != null) {
filestream.close();
}
if (outstream != null) {
outstream.close();
}
}
}
The only issue I have is setting the file path. The path is
C:\Users\Chris\AppData\Roaming\NetBeans\7.2.1\config\GF3\domain1\
But I want it to save in
Project-war/web/images
Any ideas?
I'm extracting a file from a zip archive using this code (omitting all the catch statements and other initialization statements):
zipInputStream = new ZipInputStream(new FileInputStream(file));
zipFile = new ZipFile(file);
for (Enumeration<?> em = zipFile.entries(); em.hasMoreElements();) {
String extractedFileName = em.nextElement().toString();
ZipEntry outerZipEntry = zipInputStream.getNextEntry();
if (outerZipEntry.getName().contains(searchString)) {
extractedFile = new File(outputDir + outerZipEntry.getName());
out = new FileOutputStream(outputDir + extractedFileName);
byte[] buf = new byte[1024];
int len;
while ((len = zipInputStream.read(buf)) > 0) {
out.write(buf, 0, len);
}
break;
}
}
This code works fine when extracting a file in say, /archive.zip/file_i_need.txt.
But when I'm trying to extract a file from /archive.zip/folder1/file_i_need.txt, I get an exception java.lang.NullPointerException when I try to use readLine() to read the file in:
String line = null ;
BufferedReader input = new BufferedReader(newFileReader(extractedFile)) ;
while( (line = input.readLine() ) != null ) {
...
}
I've tested it on both cases and it seems like this code will not work when the file is inside a folder because the extractedFileName is 'folder/file_i_need.txt' compared to just 'file_i_need.txt'.
Any suggestions you can recommend?
Thanks!
extractedFile = new File(outputDir + outerZipEntry.getName());
The problem is you're not taking into account that the entries name may contain a path element, which you are not creating, you simply try an write to the file. Why this doesn't produce an error, I'm not sure.
Are you writing these files on Windows?? This would create a file like folder1/file_i_need.txt on the file system, which is probably invalid at some level :P
Try extracting the file name from the ZipEntry
String name = outerZipEntry.getName();
name = name.substring(name.lastIndexOf("/") + 1);
Obviously, check that name actually contains a "/" first ;)
UPDATE
While I'm at it, this looks wrong
extractedFile = new File(outputDir + outerZipEntry.getName());
out = new FileOutputStream(outputDir + extractedFileName);
Basically your saying outputDir + outerZipEntry.getName() + (outputDir + outerZipEntry.getName())
UPDATE
I tested this on Windows and I get a FileNotFoundException when I try and write the file to a path that does not exist
I also tested it on my MaC and I get a FileNotFoundException
I don't know what your error handling is doing, but it's doing it wrong.
I think your issue is that you can't open a FileOutputStream on line out = new FileOutputStream(outputDir + extractedFileName);. You can't open a stream because if extractedFileName is folder1/file_i_need.txt and outputDir is, for example, C:/OutputDir then you're trying to open a stream on C:/OutputDirfolder1/file_i_need.txt. Such directory doesn't exist and out becomes null.
The post I was referring to in my comment does have a unzip operation, and ther you can see the special handling of directory entries in a zip file.
You are iterating over zip entries in two different ways:
Iteration 1:
for (Enumeration<?> em = zipFile.entries(); em.hasMoreElements();) {
Iteration 2:
ZipEntry outerZipEntry = zipInputStream.getNextEntry();
Just do one or the other. Either use the ZipFile API or the ZipInputStream API. I strongly suspect that is where the NullPointerException is coming from.
I need to create a File object out of a file path to an image that is contained in a jar file after creating a jar file. If tried using:
URL url = getClass().getResource("/resources/images/image.jpg");
File imageFile = new File(url.toURI());
but it doesn't work. Does anyone know of another way to do it?
To create a file on Android from a resource or raw file I do this:
try{
InputStream inputStream = getResources().openRawResource(R.raw.some_file);
File tempFile = File.createTempFile("pre", "suf");
copyFile(inputStream, new FileOutputStream(tempFile));
// Now some_file is tempFile .. do what you like
} catch (IOException e) {
throw new RuntimeException("Can't create temp file ", e);
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
Don't forget to close your streams etc
This should work.
String imgName = "/resources/images/image.jpg";
InputStream in = getClass().getResourceAsStream(imgName);
ImageIcon img = new ImageIcon(ImageIO.read(in));
Usually, you can't directly get a java.io.File object, since there is no physical file for an entry within a compressed archive. Either you live with a stream (which is best most in the cases, since every good API can work with streams) or you can create a temporary file:
URL imageResource = getClass().getResource("image.gif");
File imageFile = File.createTempFile(
FilenameUtils.getBaseName(imageResource.getFile()),
FilenameUtils.getExtension(imageResource.getFile()));
IOUtils.copy(imageResource.openStream(),
FileUtils.openOutputStream(imageFile));
You cannot create a File object to a reference inside an archive. If you absolutely need a File object, you will need to extract the file to a temporary location first. On the other hand, most good API's will also take an input stream instead, which you can get for a file in an archive.
Use Case
I need to package up our kml which is in a String into a kmz response for a network link in Google Earth. I would like to also wrap up icons and such while I'm at it.
Problem
Using the implementation below I receive errors from both WinZip and Google Earth that the archive is corrupted or that the file cannot be opened respectively. The part that deviates from other examples I'd built this from are the lines where the string is added:
ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));
Please point me in the right direction to correctly write the string so that it is in doc.xml in the resulting kmz file. I know how to write the string to a temporary file, but I would very much like to keep the operation in memory for understandability and efficiency.
private static final int BUFFER = 2048;
private static void kmz(OutputStream os, String kml)
{
try{
BufferedInputStream origin = null;
ZipOutputStream out = new ZipOutputStream(os);
out.setMethod(ZipOutputStream.DEFLATED);
byte data[] = new byte[BUFFER];
File f = new File("./icons"); //folder containing icons and such
String files[] = f.list();
if(files != null)
{
for (String file: files) {
LOGGER.info("Adding to KMZ: "+ file);
FileInputStream fi = new FileInputStream(file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(file);
out.putNextEntry(entry);
int count;
while((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));
}
catch(Exception e)
{
LOGGER.error("Problem creating kmz file", e);
}
}
Bonus points for showing me how to put the supplementary files from the icons folder into a similar folder within the archive as opposed to at the same layer as the doc.kml.
Update Even when saving the string to a temp file the errors occur. Ugh.
Use Case Note The use case is for use in a web app, but the code to get the list of files won't work there. For details see how-to-access-local-files-on-server-in-jboss-application
You forgot to call close() on ZipOutputStream. Best place to call it is the finally block of the try block where it's been created.
Update: To create a folder, just prepend its name in the entry name.
ZipEntry entry = new ZipEntry("icons/" + file);