I am currently using Uploadify (Flash + Ajax) to the Servlet (Commons Upload with OWASP ESAPI overlay) with success, but I was wondering how I would go about building in HTML5 support, or rather HTML5 with Flash support.
I know how to get the HTML5 drag and drop working, but I can't quite figure out the mechanics of a Java Servlet connection and/or backend.
Drag and drop file uploads happen when you drag one or more files from an underlying platform's file manager and drop them onto a web page for upload. A preview of the image indicates the upload has begun. Many JavaScript libraries create this type of drag and drop file upload feature with a few lines of code.
When you drag any image file over the drag area, the border of the container also changed to solid, and the text "Drag & Drop to upload file" also changed to "Release to upload file". When you release your image file in the drag area, immediately the preview of that image will appear.
Code a Java Servlet to handle the file upload process; Annotate the file upload Servlet with the @MultipartConfig annotation; In the Servlet, save the uploaded file to the server's file system; and. Send a response back to the browser to indicate that the file successfully uploaded.
I know how to get the HTML5 DnD working, but I can't quite figure out the mechanics of a Java Servlet connection and/or backend.
It's not different from when using a regular <form enctype="multipart/form-data">
. All you need to do is to get that HTML5/JS code to send a multipart/form-data
request with the dropped file, exactly the same kind of request as it would have been sent with a regular <input type="file">
field. I'll assume that you just can't figure out how to achieve exactly that with HTML5/JS.
You can utilize the new HTML5 File
API, XHR2 FormData
and XMLHttpRequestUpload
APIs for this.
Here's a kickoff example of how your drop
event handler should look like:
function dropUpload(event) { event.stopPropagation(); event.preventDefault(); var formData = new FormData(); formData.append("file", event.dataTransfer.files[0]); var xhr = new XMLHttpRequest(); xhr.open("POST", "uploadServlet"); xhr.send(formData); }
That's it. This example assumes that the servlet is mapped on a URL pattern of /uploadServlet
. In this example, the file is then available in Apache Commons FileUpload the usual way as a FileItem
instance with a field name of file
.
For more advanced stuff like attaching event handlers for monitoring the progress and like, checkout the following blogs:
I've played somewhat around it with the following SSCCE:
<!DOCTYPE html> <html lang="en"> <head> <title>HTML5 drag'n'drop file upload with Servlet</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", "uploadServlet", 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>
and this UploadServlet
utilizing the new Servlet 3.0 HttpServletRequest#getPart()
API:
@MultipartConfig @WebServlet("/uploadServlet") public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Part file = request.getPart("file"); String filename = getFilename(file); InputStream filecontent = file.getInputStream(); // ... Do your file saving job here. response.setContentType("text/plain"); response.setCharacterEncoding("UTF-8"); response.getWriter().write("File " + filename + " successfully uploaded"); } 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; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With