July 23, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

5 Java Upload Applets for Your Web Applications

  • April 25, 2012
  • By Constantin Marian Alin
  • Send Email »
  • More Articles »

In this article, I profile five upload solutions for Java Web applications:

  • YUI Uploader
  • GWTUpload
  • Postlet Applet
  • JUpload Applet
  • PrimeFaces Upload

The article will not help you decide which one to choose; it just presents the features of the five solutions for Java developers.

For additional reading on Java upload solutions, see my two previously published JavaBoutique articles on COS and SWFUpload and "FileUpload."

YUI Uploader

The YUI Uploader is a great upload component from Yahoo. This customizable component has a great design that can accomplish everything from simple uploads to complex ones.

YUI Uploader Capabilities

Specifically, the YUI Uploader allows for these features (taken from YUI Uploader site):

  • Multiple file selection in a single "Open File" dialog.
  • File extension filters to facilitate the user's selection.
  • Progress tracking for file uploads.
  • A range of available file metadata: filename, size, date created, date modified, and author.
  • A set of events dispatched on various aspects of the file upload process: file selection, upload progress, upload completion, etc.
  • Inclusion of additional data in the file upload POST request.
  • Faster file upload on broadband connections due to the modified SEND buffer size.
  • Same-page server response upon completion of the file upload.

Implementing YUI Uploader

In this section, you will see how to implement the YUI Uploader into a Web application built in a Java context. To start, you must download the YUI Uploader. Depending on the Web application context, to use the Uploader Control, include the following source files in your Web page (in this example I stored the YUI Uploader into a folder named /yui under application root):


<script type="text/javascript" src="yui/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="yui/build/element/element-min.js"></script>
<script type="text/javascript" src="yui/build/uploader/uploader-min.js"></script>

Next, you can place the code necessary to configure the YUI Uploader. First, you can see a few details about each representative chunk of code, and after that you will see the code.

First of all, you need to specify the path (relative to the page or absolute) of the uploader.swf file to the location of the HTML page in which a Uploader Control instance will appear and then render the uploader as a button.


// Instantiate the uploader and write it to its placeholder div.
YAHOO.widget.Uploader.SWFURL = "yui/resources/uploader.swf";
var uploader = new YAHOO.widget.Uploader( "uploaderUI",
                                             "yui/resources/selectFileButton.png");

The Uploader has a number of methods that allow you to manage the upload process and dispatch various events for different aspects of the upload process. To add event listeners to various events called by the uploader you may do something like this:


// Add event listeners to various events on the uploader.
// Methods on the uploader should only be called once the contentReady event has 
// fired.
uploader.addListener('contentReady', handleContentReady);
uploader.addListener('fileSelect',onFileSelect)
uploader.addListener('uploadStart',onUploadStart);
uploader.addListener('uploadProgress',onUploadProgress);
uploader.addListener('uploadCancel',onUploadCancel);
uploader.addListener('uploadComplete',onUploadComplete);
uploader.addListener('uploadCompleteData',onUploadResponse);
uploader.addListener('uploadError', onUploadError);

Now you need to define the event handlers. The first event that you need to create should be the contentReady, which will enable the logging output in the uploader (the log messages will be output both to the YUI Logger and the Flash trace output), disallow multiple file selection and set file filters to filter user selection.


function handleContentReady () {
   // Allows the uploader to send log messages to trace, as well as to YAHOO.log
   uploader.setAllowLogging(true);
 
   // Restrict selection to a single file (that's what it is by default,
   // just demonstrating how).
   uploader.setAllowMultipleFiles(false);
  
   // New set of file filters.   
   var ff = new Array({description:"Images", extensions:"*.txt;*.jpg;*.png;*.gif"});
                     
   // Apply new set of file filters to the uploader.
   uploader.setFileFilters(ff);
  }

When the "Upload File" button is clicked, the upload function is called.


// Initiate the file upload. Since there's only one file, 
// I can use either upload() or uploadAll() call. fileList 
// needs to have been populated by the user.
function upload() {
 if (fileID != null) {
 uploader.upload(fileID, "http://localhost:8085/YUI_upload/oreilly_upload");
 fileID = null;
   }
}

When a file is selected, record the ID of the selected file, disable the uploader UI, display the name of the file and reset the progress bar.


// Fired when the user selects files in the "Browse" dialog
// and clicks "Ok".
function onFileSelect(event) {
 for (var item in event.fileList) {
     if(YAHOO.lang.hasOwnProperty(event.fileList, item)) {
   YAHOO.log(event.fileList[item].id);
   fileID = event.fileList[item].id;
  }
 }
 uploader.disable();

 var filename = document.getElementById("fileName");
 filename.innerHTML = event.fileList[fileID].name;
 var progressbar = document.getElementById("progressBar");
 progressbar.innerHTML = "";
}

The next function handles uploadProgress events and draws a progress bar of the correct size.


// Do something on each file's upload progress event.
function onUploadProgress(event) {
 prog = Math.round(300*(event["bytesLoaded"]/event["bytesTotal"]));
   progbar = "<div style=\"background-color: #f00; height: 5px; width: " + 
                                                                  prog + "px\"/>";
 var progressbar = document.getElementById("progressBar");
 progressbar.innerHTML = progbar;
}

Next, you need to handle the uploadComplete event, draw a full progress bar and re-enable the uploader UI.


// Do something when each file's upload is complete.
function onUploadComplete(event) {  
 uploader.clearFileList();
 uploader.enable();
 progbar = "<div style=\"background-color: #CCCCCC; height: 5px; width: 300px\"/>";
 var progressbar = document.getElementById("progressBar");
 progressbar.innerHTML = progbar;
         var filename = document.getElementById("fileName");
         filename.innerHTML = "";
}

The code without comments is shown below:


...
<style type="text/css">
     .uploadButton a, .clearButton a {
          display:block;
          width:100px;
          height:40px;
          text-decoration: none;
          margin-left:5px;
     }
     
     .uploadButton a {
          background: url("yui/resources/uploadFileButton.png") 0 0 no-repeat;
     }
     
     .clearButton a {
          background: url("yui/resources/clearListButton.png") 0 0 no-repeat;
     }
     
    .uploadButton a:visited, .clearButton a:visited {
          background-position: 0 0;
     }
     
    .uploadButton a:hover, .clearButton a:hover {     
          background-position: 0 -40px;
     }
     
    .uploadButton a:active, .clearButton a:active {
          background-position: 0 -80px;
     }
</style>

<div>
 <div id="fileProgress" style="border: black 1px solid; width:300px; height:40px;float:left">
  <div id="fileName" style="text-align:center; margin:5px; font-size:15px; width:290px; height:25px; overflow:hidden"></div>
  <div id="progressBar" style="width:300px;height:5px;background-color:#CCCCCC"></div>
 </div>
 <div id="uploaderUI" style="width:100px;height:40px;margin-left:5px;float:left"></div>
 <div class="uploadButton" style="float:left"><a class="rolloverButton" href="#" onClick="upload(); return false;"></a></div>
 <div class="clearButton" style="float:left"><a class="rolloverButton" href="#" onClick="handleClearFiles(); return false;"></a></div>
</div>

 <script type="text/javascript">

YAHOO.widget.Uploader.SWFURL = "yui/resources/uploader.swf";
     
     var uploader = new YAHOO.widget.Uploader( "uploaderUI", "yui/resources/selectFileButton.png" );
     
     uploader.addListener('contentReady', handleContentReady);
     uploader.addListener('fileSelect',onFileSelect)
     uploader.addListener('uploadStart',onUploadStart);
     uploader.addListener('uploadProgress',onUploadProgress);
     uploader.addListener('uploadCancel',onUploadCancel);
     uploader.addListener('uploadComplete',onUploadComplete);
     uploader.addListener('uploadCompleteData',onUploadResponse);
     uploader.addListener('uploadError', onUploadError);

    // Variable for holding the selected file ID.
     var fileID;
     
     function handleClearFiles() {
     uploader.clearFileList();
     uploader.enable();
     fileID = null;
     
     var filename = document.getElementById("fileName");
     filename.innerHTML = "";
     
     var progressbar = document.getElementById("progressBar");
     progressbar.innerHTML = "";
     }

     function handleContentReady () {
          uploader.setAllowLogging(true);
          uploader.setAllowMultipleFiles(false);     
          var ff = new Array({description:"Images", extensions:"*.txt;*.jpg;*.png;*.gif"});                             
          uploader.setFileFilters(ff);
     }

     function upload() {
     if (fileID != null) {
          uploader.upload(fileID, "http://localhost:8080/YUIupload/oreilly_upload");
          fileID = null;
       }
     }
 
     function onFileSelect(event) {
          for (var item in event.fileList) {
              if(YAHOO.lang.hasOwnProperty(event.fileList, item)) {
                    YAHOO.log(event.fileList[item].id);
                    fileID = event.fileList[item].id;
               }
          }
          uploader.disable();
          
          var filename = document.getElementById("fileName");
          filename.innerHTML = event.fileList[fileID].name;
          
          var progressbar = document.getElementById("progressBar");
          progressbar.innerHTML = "";
     }

    // Do something on each file's upload start.
     function onUploadStart(event) {
     
     }
     
     function onUploadProgress(event) {
          prog = Math.round(300*(event["bytesLoaded"]/event["bytesTotal"]));
            progbar = "<div style=\"background-color: #f00; height: 5px; width: " + prog + "px\"/>";

          var progressbar = document.getElementById("progressBar");
          progressbar.innerHTML = progbar;
     }
 
     // Do something when each file's upload is complete.
     function onUploadComplete(event) {  
          uploader.clearFileList();
          uploader.enable();
          
          progbar = "<div style=\"background-color: #CCCCCC; height: 5px; width: 300px\"/>";
          var progressbar = document.getElementById("progressBar");
          progressbar.innerHTML = progbar;

                var filename = document.getElementById("fileName");
          filename.innerHTML = "";
     }
 
     // Do something if a file upload throws an error.
     // (When uploadAll() is used, the Uploader will
     // attempt to continue uploading.
     function onUploadError(event) {           
     }
     
     // Do something if an upload is cancelled.
     function onUploadCancel(event) {
     }
     
     // Do something when data is received back from the server.
     function onUploadResponse(event) {  
          alert("Server response successfully received!");
     }

</script>
...

For this application you can use the COS described in the article COS and SWFUpload for End-to-end Java File Upload. The result of this application is shown in the figure below.

Java File Upload

Java Upload with Postlet Applet

Postlet is a Java applet used for uploading files to Web servers. It supports multiple file uploading using a nice, easy-to-use design.

Postlet provides four main features:

  • File progress bar
  • Error checking
  • Easy selection and upload of multiple files
  • Resizing of images over a set size

To start, you must download Postlet, the Java applet upload, from postlet.com. Extract the postlet.jar under your Web application.

The applet is customizable through a set of parameters:

  • destination: the URL to your servlet that will accept file upload
  • language: the language to use for Postlet's user interface
  • backgroundcolour: the color to use for Postlet background
  • tableheadercolour: the color to use for the text of the Table Headers
  • tableheaderbackgroundcolour: the color to use for the background of the Table Headers
  • fileextensions: a list of the file extensions
  • warnmessage: enables the ability to show a warning message once the upload button is pressed. Its value can be "true" or "false."
  • autoupload: enables the ability to automatically upload files once they are selected. Its value can be "true" or "false."
  • helpbutton: enables the ability to show a help button. It works on versions newer than 0.10.0, and its value can be "true" or "false."
  • maxpixels: the maximum number of pixels allowed for GIF, JPEG and PNG images when there are uploaded. If files exceed this limit, they are resized to the set limit. If they are resized GIF images, they are uploaded as PNG images. It works on versions newer than 0.13.
  • helppage: the URL to show if the user clicks the help button. The default URL is to http://www.postlet.com/help/.
  • maxthreads: the maximum number of connections to use. It can take values from 1 to 5.
  • Endpage: the URL to take the user to once upload has completed.
  • Failedfilesmessage: enables the ability to show the popup message listing the files that failed to upload

A possible configuration is listed below:


<applet name="postlet" code="Main.class" 
        archive="./applets/postlet.jar" width="850" height="150" mayscript>
  <param name = "maxthreads" value = "5" />
  <param name = "language" value = "" />
  <param name = "type" value = "application/x-java-applet;version=1.3.1" />
  <param name = "destination" 
         value = "http://localhost:8085/PostletUpload/applet_upload" />
  <param name = "backgroundcolour" value = "56328145" />
  <param name = "tableheaderbackgroundcolour" value = "24279327" />
  <param name = "tableheadercolour" value = "0" />
  <param name = "warnmessage" value = "false" />
  <param name = "autoupload" value = "false" />
  <param name = "helpbutton" value = "false" />
  <param name = "fileextensions" value = "Image Files,jpg,gif,jpeg" />
  <param name = "endpage" value = "[*** ENDPAGE URL***]" />
  <param name = "helppage" 
         value = "http://www.postlet.com/help/?thisIsTheDefaultAnyway" />
</applet>

When the uploads ends, a JavaScript function can fire up a message:


<script type="text/javascript">      
     function postletFinished(){ 
       alert("Postlet Applet Succesfully Accomplished its Job!"); }
    </script>

For this application (on the server side) you can use the COS described in this article COS and SWFUpload for End-to-End Java File Upload. Notice the messages returned by the server should by specific to Postlet Upload. You can see the entire list of possible responses. The COS implementation for Postlet Upload is:


public class AppletUploadServlet extends HttpServlet {

 protected void processRequest(HttpServletRequest request, 
    HttpServletResponse response) throws ServletException, IOException {        
     
  final int permitedSize = 314572800;  //~ 300 MB bytes
  final String[] extensions = {".zip",".xls"};
         
  StringBuffer answer = new StringBuffer();
  answer.append("POSTLET REPLY\nPOSTLET:YES\nEND POSTLET REPLY\n");      
       
  PrintWriter out = response.getWriter();
  response.setContentType("text/html;charset=UTF-8");
  response.setHeader("Cache-Control", "no-cache");
  response.setHeader("Pragma", "No-cache");
  response.setDateHeader("Expires",0);  
    
  try{               
     String strDirectory = "files";
     String uploadPath = request.getRealPath("//WEB-INF//"+strDirectory+"//");

    //or, like this, from web.xml       
     String uploadPath_rezerva = request.getRealPath(getServletConfig().
                 getInitParameter("uploadPath"));

     MultipartRequest multipartRequest = new MultipartRequest(request,
           uploadPath, permitedSize, "ISO-8859-1", new DefaultFileRenamePolicy()); 
          
     Enumeration files = multipartRequest.getFileNames(); 
   
 String extension1 = "";
        String extension2 = "";
        String filename = "";
          
        while (files.hasMoreElements()) 
        { 
               String name = (String)files.nextElement(); 
               filename = multipartRequest.getFilesystemName(name); 
               String originalFilename = multipartRequest.getOriginalFileName(name); 
                                                
      extension1 = filename.substring(filename.length() - 4, filename.length());
             extension2 = originalFilename.substring(originalFilename.length() - 4, 
             originalFilename.length());
                                                            
                //use O'Reilly COS
                File currentFile = multipartRequest.getFile(name);
                }
                         
       out.println(answer);

       }catch (Exception exception)
          {                     
   answer.delete(0, answer.length());
          answer.append("POSTLET REPLY\nPOSTLET:NO\nPOSTLET:SERVER ERROR\n
                               POSTLET:ABORT ALL\nEND POSTLET REPLY\n");
          
          out.println(answer);
   } finally { if(out != null) {out.close();} }     
   } 
}

The result of this application is shown in the figure below:

Java Upload

Java Upload with PrimeFaces

In the past couple of year, I've noticed a lot of interest in the PrimeFaces upload solution. I can't say that I'm surprised, since it is a very good-looking upload solution that is easy to configure and use. Therefore, I've decided to provide a small guide to implementing the PrimeFaces upload under a Tomcat 6 Web application.

You will need the following JARs, under your /lib folder:

  • primeface-2.2.RC2.jar (this is what I used, but you can take the latest PrimeFaces library from the PrimeFaces site).
  • jsf-api-2.0.2-FCS.jar (again, use the latest version if you think that you need it)
  • jsf-impl-2.0.2-FCS.jar
  • el-api-2.2.jar
  • el-impl-2.2.jar
  • commons-io-1.4.jar
  • commons-fileupload-1.2.jar

To start, I've configured the application descriptor and web.xml (depending on the PrimeFaces version, these configurations may be slightly different). In this descriptor, I've configured the PrimeFaces upload filter:


<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" 
    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>            
    <context-param>
        <description>Context param for JSTL 1.2 to work in Tomcat 6 sun RI
        </description>
        <param-name>com.sun.faces.expressionFactory</param-name>
        <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
    </context-param>
    <context-param>
        <description>Parameter required by Mojarra 2.0</description>
        <param-name>com.sun.faces.allowTextChildren</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
        <param-value>true</param-value>
    </context-param>    
    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
        <init-param>
            <param-name>thresholdSize</param-name>
            <param-value>2097152</param-value>
        </init-param>      
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>  
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>   
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>   
</web-app>

Next, I wrote a simple JSF page to test the PrimeFaces upload component:


<?xml version="1.0" encoding="UTF-8"?>                              

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
</h:head>
 <h:body>
 <h:outputText value="Select the files to upload (maxim 2MB):"/>
 <p:growl id="uploadMessages" showSummary="true" showDetail="true"/>
 <h:form enctype="multipart/form-data" prependId="false">
  <p:fileUpload update="uploadMessages"   
                fileUploadListener="#{fileUploadController.handleFileUpload}" 
                sizeLimit="2097152" 
                multiple="true" 
                label="choose" 
                allowTypes="*.jpg;*.png;*.gif;" 
                description="Images"/>  
 </h:form>
 </h:body>
</html>

As you can see, p:fileUpload is very flexible and customizable, allowing us to specify upload characteristics with a few simple attributes. Going further, I need a managed bean capable of dealing with upload itself. A possible implementation is listed below (probably not the best, but for sure not the worst):


package com.extensions;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.event.FileUploadEvent;

@ManagedBean(name = "fileUploadController")
@RequestScoped
public class uploadFilesBean {
   
    //Primitives
    private static final int BUFFER_SIZE = 6124;    
    private String folderToUpload;
    
    /** Creates a new instance of UploadBean */
    public uploadFilesBean() {
    }
    
    public void handleFileUpload(FileUploadEvent event) {
       
    ExternalContext extContext=FacesContext.getCurrentInstance().getExternalContext();
            
    File result = new File(extContext.getRealPath("//WEB-INF//files//" + 
          event.getFile().getFileName()));
    //System.out.println(extContext.getRealPath("//WEB-INF//files//" + 
    //      event.getFile().getFileName()));

    try {
        FileOutputStream fileOutputStream = new FileOutputStream(result);

        byte[] buffer = new byte[BUFFER_SIZE];

        int bulk;
        InputStream inputStream = event.getFile().getInputstream();
        while (true) {
               bulk = inputStream.read(buffer);
               if (bulk < 0) {
                   break;
                }
               fileOutputStream.write(buffer, 0, bulk);
               fileOutputStream.flush();
         }

        fileOutputStream.close();
        inputStream.close();

       FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName()
                                                                  + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);

        } catch (IOException e) {
            e.printStackTrace();

            FacesMessage error = new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                                                 "The files were not uploaded!", "");
            FacesContext.getCurrentInstance().addMessage(null, error);
     }       
   }    
}

The uploaded files go to the /WEB-INF/files folder. Here it is a nice screenshot of PrimeFaces upload.

Java Upload

The PrimeFaces upload example in this section was simple. Visit the PrimeFaces ShowCase site, where you can see more types of uploads.


Tags: Java, upload files

Originally published on http://www.developer.com.

Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel