HTML5 Drag and Drop File Uploader with Java Servlet is not working when placed in a sub directory

Hi there,

I have a HTML5 Drag and Drop file uploader which connects to the backend Servlet. I am using Java 8 on Windows 8.1 with Eclipse IDE

I have three questions

1) When I place the HTML5 file under the WebContent (i.e in the web root folder) it works but when I place the HTML5 in a sub folder which is the actual destination, it fails  to upload the file.

WebContent
      |
       ----elk-upload-dnd.html
      |
       ----elkUploader (Sub folder)
                  |
                  ----elk-upload-dnd.html (When the file is moved here i.e to the subfolder, it is not uploading)


2) I can't delete the uploaded file, all I have to do is stop the Tomcat server which is configured through the Eclipse IDE and then delete the file. How can I delete the file programatically?

3) The folder which its get uploaded in Windows is "C:/logs/elk/apache/ " but the application is being developer in Windows, Mac and Linux and finally it gets deployed in Linux. How to make the application to upload the file into the right folder when running in Windows, Linux and Mac? Is there any standard way to achieve portability across platforms?

HTML5 Code

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>ELK (HTML5) file upload using Drag and Drop</title>
        <script>
            window.onload = function() {
                var dropbox = document.getElementById("dropbox");
                dropbox.addEventListener("dragenter", noop, false);
                dropbox.addEventListener("dragexit", noop, false);
                dropbox.addEventListener("dragover", noop, false);
                dropbox.addEventListener("drop", dropUpload, false);
            }

            function noop(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            function dropUpload(event) {
                noop(event);
                var files = event.dataTransfer.files;

                for (var i = 0; i < files.length; i++) {
                    upload(files[i]);
                }
            }

            function upload(file) {
                document.getElementById("status").innerHTML = "Uploading " + file.name;

                var formData = new FormData();
                formData.append("file", file);

                var xhr = new XMLHttpRequest();
                xhr.upload.addEventListener("progress", uploadProgress, false);
                xhr.addEventListener("load", uploadComplete, false);
                xhr.open("POST", "ELKFileUploader", true); // If async=false, then you'll miss progress bar support.
                xhr.send(formData);
            }

            function uploadProgress(event) {
                // Note: doesn't work with async=false.
                var progress = Math.round(event.loaded / event.total * 100);
                document.getElementById("status").innerHTML = "Progress " + progress + "%";
            }

            function uploadComplete(event) {
                document.getElementById("status").innerHTML = event.target.responseText;
            }
        </script>
        <style>
            #dropbox {
                width: 300px;
                height: 200px;
                border: 1px solid gray;
                border-radius: 5px;
                padding: 5px;
                color: gray;
            }
        </style>
    </head>
    <body>
        <div id="dropbox">Drag and drop a file here...</div>
        <div id="status"></div>
    </body>
</html>

Open in new window


Java Servlet Code

package com.example;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * Servlet implementation class ELKFileUploader
 */
@MultipartConfig
@WebServlet(urlPatterns = { "/ELKFileUploader" })

public class ELKFileUploader extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ELKFileUploader() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Part file = request.getPart("file");
        String filename = getFilename(file);
        InputStream filecontent = file.getInputStream();        
        
        FileOutputStream outputStream =  new FileOutputStream(new File("C:/logs/elk/apache/" + filename));
                
        int read = 0;
		byte[] bytes = new byte[1024];

		while ((read = filecontent.read(bytes)) != -1) {
			outputStream.write(bytes, 0, read);
		}

        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("File " + filename + " successfully uploaded");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
	
	private static String getFilename(Part part) {
        for (String cd : part.getHeader("content-disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
            }
        }
        return null;
    }
}

Open in new window

ShajiAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mccarlIT Business Systems Analyst / Software DeveloperCommented:
Answers...

1) The URL that the HTML/javascript code uses to "post" the file to is relative, so that is why when it is in the root directory, it posts to "/ELKFileUploader" but if you put it in the sub-directory that you mention, it will post it to "/elkUploader/ELKFileUploader". If this is what you really want, then you also have to change the path that the Java Servlet is configured to use to the same, ie. change it on line 20 of the Java code you posted.

2) The outputStream isn't being closed, try adding the following line at line 48 in the above Java code (ie. just after the "while" loop that writes all the data out to the outputStream)...
		outputStream.close();

Open in new window


3) The output directory is hard coded on line 40 of the Java servlet code. Normally you would make this some sort of parameter. The options would include to make it a Servlet parameter, use a Java "system property" or use an "environment variable" from the operating system. The choice is up to you, there is no real "standard" way out of those (or other) options.


To wrap it all up, here is some updated Java code that covers all three questions...

package com.example;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * Servlet implementation class ELKFileUploader
 */
@MultipartConfig
@WebServlet(urlPatterns = { "/elkUploader/ELKFileUploader" })

public class ELKFileUploader extends HttpServlet {
	private static final long serialVersionUID = 1L;
       private String outputDirectory = "C:/logs/elk/apache/";    // This is the default if no environment variable is set

    /**
     * @see HttpServlet#HttpServlet()
     */
    public ELKFileUploader() {
        super();

        String var = System.getenv("ELK_UPLOAD_DIR");          // Now you can control the directory files are written to by setting this OS environment variable
        if (var != null) {
            outputDirectory = var;
        }
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Part file = request.getPart("file");
        String filename = getFilename(file);
        InputStream filecontent = file.getInputStream();        
        
        FileOutputStream outputStream =  new FileOutputStream(new File(outputDirectory + filename));
                
        int read = 0;
		byte[] bytes = new byte[1024];

		while ((read = filecontent.read(bytes)) != -1) {
			outputStream.write(bytes, 0, read);
		}
		outputStream.close();				// Ensures that the file is closed, allowing it to be deleted/moved/etc without shutting down Tomcat

        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("File " + filename + " successfully uploaded");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
	
	private static String getFilename(Part part) {
        for (String cd : part.getHeader("content-disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
            }
        }
        return null;
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ShajiAuthor Commented:
Thanks mccarl, it is working like a champ.
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
You're welcome!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.