Struts: Upload file using Struts and Generates unique ID for file name

written by aext on June 28, 2008 in Tutorials with 2 comments

Someone finding the way to upload file with struts, it’s simple…You only create form with Struts: Form class with file property is FormFile. But,..how to upload file to server with unique name in folder if some file has same name ???. Now, with this post, you’ll resolve it, very simple!!!.

First, simply create your Struts form class, below is UploadFileForm, class extends ValidatorActionForm because i want to validate Form for uploading, class:

package prlamnguyen.struts.form;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import org.apache.struts.validator.ValidatorActionForm;

/**
* Upload File Form Class.
*
* @author prlamnguyen
* @link http://prlamnguyen.blogspot.com/2008/06/upload-file-using-struts-and-generates.html
*/

public class UploadFileForm extends ValidatorActionForm {


   /*
   * Extends ValidatorActionForm if you want to validate form
   */

   /** image property */
   private String fileName;


   /** fileImage property */
   private FormFile file


   /**
   * @return the file
   */
   public FormFile getFile() {
      return file;
   }


   /**
   * @return the fileName
   */
   public String getFileName() {
      return fileName;
   }


   /**
   * @param file the file to set
   */
   public void setFileImage(FormFile file){
      this.file = file;
   }


   /**
   * @param fileName the fileName to set
   */
   public void setImage(String fileName) {
      this.fileName = fileName;
   }


   /**
   * Method validate
   * @param mapping
   * @param request
   * @return ActionErrors
   */
   public ActionErrors validate(ActionMapping mapping,
   HttpServletRequest request) {
      // Validate your form if you want
      // This helpful for validate type of file, size, extension of file ....
      return null;
   }


   /**
   * Method reset
   * @param mapping
   * @param request
   */
   public void reset(ActionMapping mapping, HttpServletRequest request) {
      // Reset your form input
   }

}

Above is UploadFileForm class, we have 2 properties: (String) fileName and (FormFile)file , with property file, you must import org.apache.struts.upload.FormFile which is struts capabilities, with MyEclipse 3.x or above, you can do that simply.

Now, we must create action class for struts, name of action class is UploadFileAction:

package prlamnguyen.struts.action;


import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import prlamnguyen.struts.form.UploadFileForm;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;


/**
* Creation date: 05-31-2008
*
* Upload File Action Class.
*
* @author prlamnguyen
* @link http://prlamnguyen.blogspot.com/2008/06/upload-file-using-struts-and-generates.html
*
* Definition:
* @struts.action path="/uploadFile" name="uploadFileForm" input="/upload_file.jsp" scope="request" validate="true"
* @struts.action-forward name="failed" path="/upload_file.jsp"
* @struts.action-forward name="success" path="/upload_successful.jsp"
*/
public class UploadFileAction extends Action {
   /*
   * Generated Methods
   */



   /**
   *
   * @param uploadForm
   * @return
   */
   public String uploadFile(UploadFileForm uploadForm) {
      // Process the FormFile
      FormFile myFile = uploadForm.getFile();
      String fileName="default";
      // Get the file name
      try {
          // Precreate an unique file and then write the InputStream of the uploaded file to it.
          File uniqueFile = DoFile.uniqueFile(new File("your file patch"), myFile.getFileName());
          DoFile.write(uniqueFile, myFile.getInputStream());
          fileName = uniqueFile.getName();

          // Show succes message.
          System.out.println("Upload file complete");

      } catch (IOException e) {

          // Show error message.
          System.out.println("Upload file failed");

          // Always log stacktraces.
          e.printStackTrace();
      }
      return fileName;
   }

   /**
   * Method execute
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @return ActionForward
   */
   public ActionForward execute(ActionMapping mapping, ActionForm form,
       HttpServletRequest request, HttpServletResponse response) {
       UploadFileForm uploadForm = (UploadFileForm) form;
       // to do execute
       ActionForward forward = new ActionForward();

       image = uploadImage(uploadForm);


       return forward = mapping.findForward("success");
   }
}


Ukie, all important thing done, DoFile above is one class file you must declare, and Struts must be config-ed:

  • DoFile Class:

/**
* Generate unique file based on the given path and name. If the file exists, then it will
* add "[i]" to the file name as long as the file exists. The value of i can be between
* 0 and 2147483647 (the value of Integer.MAX_VALUE).
* @param filePath The path of the unique file.
* @param fileName The name of the unique file.
* @return The unique file.
* @throws IOException If unique file cannot be generated, this can be caused if all file
* names are already in use. You may consider another filename instead.
*/
public static File uniqueFile(File filePath, String fileName) throws IOException {
   File file = new File(filePath, fileName);
   if (file.exists()) {
        // Split filename and add braces, e.g. "name.ext" --> "name[", "].ext".

        String prefix;
        String suffix;
        int dotIndex = fileName.lastIndexOf(".");


       if (dotIndex > -1) {
            prefix = fileName.substring(0, dotIndex) + "[";
            suffix = "]" + fileName.substring(dotIndex);
        } else {
            prefix = fileName + "[";
            suffix = "]";
        }
       int count = 0;
        // Add counter to filename as long as file exists.

       while (file.exists()) {

          if (count < 0) { // int++ restarts at -2147483648 after 2147483647.
             throw new IOException("No unique filename available for " + fileName
                                   + " in path " + filePath.getPath() + ".");
           }
           // Glue counter between prefix and suffix, e.g. "name[" + count + "].ext".
           file = new File(filePath, prefix + (count++) + suffix);

        }
   }

   return file;
}

/**
* Write byte inputstream to file. If file already exists, it will be overwritten.It's highly
* recommended to feed the inputstream as BufferedInputStream or ByteArrayInputStream as those
* are been automatically buffered.
* @param file The file where the given byte inputstream have to be written to.
* @param input The byte inputstream which have to be written to the given file.
* @throws IOException If writing file fails.
*/
public static void write(File file, InputStream input) throws IOException {
   write(file, input, false);
}


<form-beans >
  <form-bean name="UploadFileForm" type="prlamnguyen.struts.form.UploadFileForm" />
</form-beans>

<action-mappings >
<action
attribute="uploadForm"
    input="/upload_file.jsp"
    name="uploadFileForm"
    path="/uploadFile"
    scope="request"
    type="prlamnguyen.struts.action.UploadFileAction">
    <forward name="failed" path="/upload_file.jsp" />
    <forward name="success" path="/upload_successful.jsp" />
</action>
</action-mappings>

Done, finish is create new JSP page and create Struts Form JSP, to upload your file, form with property: file.

Now, use any edit program, create new jsp file, here i create upload_file.jsp (for input and forward failed) :

<html:form action="/uploadFile" enctype="multipart/form-data">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
 <tr>
   <td class="spectd">Chose file to upload: </td>
   <td><html:file property="file"/> <html:errors property="file"/></td>
 </tr>
</table>
<div align="center">
 <html:submit/>&nbsp;&nbsp;<html:reset/>
</div>
</html:form>


Note: you must have enctype=”multipart/form-data” to send request upload file to server.

You should create successful page to print out when upload successful. In struts config, i created config-forward “success” with upload_successful.jsp jsp page.

If you done everything above, all classes were created, build all and deploy into your server and testing from url: http://localhost:8080/UploadFile/upload_file.jsp.

All wrong please email prlam.nguyen@gmail.com or comment here.
Regard!

© 2008, Lam Duy Nguyen