Hi,

Uploading files through web applications is one of the most important job of most of the applications. Earlier to servlet3.0 specification we used to do it manually, But now from Servlet 3.0 specification a very useful feature of file upload is associated. Servlet3.0 specification introduced annotation @javax.servlet.annotation.MultipartConfig and the API javax.servlet.http.Part to simplify the file upload.

Here “javax.servlet.http.Part” represents a part or form item that was received within a multipart/form-data POST request. And the @MultipartConfig indicating that instances of the Servlet expect requests that conform to the multipart/form-data MIME type. Servlets annotated with MultipartConfig may retrieve the Part components of a given multipart/form-data request by calling getPart or getParts.

In this example we will see how to uload files using the @MultipartConfig annotation and how to use the javax.servlet.http.Part API.

Step1). Our application is going to upload the files inside the server location “${jboss.server.base.dir}/upload” directory so make sure that we create a directory with name “upload” inside “${jboss.server.base.dir}”, Which means the following path should exist: “/home/userone/jboss-as-7.1.0.CR1b/standalone/upload”

Step2). Create a Directory somewhere inside your file system where we can create our web application. Suppose i am creating a directory as “/home/userone/EE6_FileUpload_Servlet” and the create a subdirectory with name “src” inside “/home/userone/EE6_FileUpload_Servlet”

Step3). We will place a simple “index.jsp” file inside “/home/userone/EE6_FileUpload_Servlet/src” directory which will present a html form to the user so that user can browse & upload the desired file.

<html>
    <head>
        <title>FileUpload Demo</title>
    </head>
    <body bgcolor="maroon" text="white">
      <center>
        <h1>FileUpload Demo Using Servlet3.0 in JBoss AS7</h1>
        <form id="formId" action="FileUploadServlet" enctype="multipart/form-data" method="post">
          <input type="file" id="FileUploadId" name="***Upload***"  /> 
          <input type="submit" id="uploadButtonId" value="Upload Now" />
        </form>   
      </center>
    </body>
</html>

Step4). Now we will write the “FileUploadServlet.java” program inside the “/home/userone/EE6_FileUpload_Servlet/src” directory which will be responsible for uploading the file provided by end user on the JBoss Server box.

package servlets;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

//IOStream
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

//Servlet3.0 specific annotations 
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.Part;

@WebServlet(description = "FileUploadServlet Description", urlPatterns = { "/FileUploadServlet" })
@MultipartConfig(location="/home/userone/EE6_FileUpload_Servlet")

public class FileUploadServlet extends HttpServlet {
 
    private static final long serialVersionUID = 1L;
    public FileUploadServlet()
        {
          super();
          System.out.println("FileUploadServlet Initialized & Instantiated.");
        }
 
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
          PrintWriter out=response.getWriter();
          out.println("<html><head><body>");
          for (Part part : request.getParts()) 
              {
                  String fileName = "";
                  String partHeader = part.getHeader("content-disposition");
                  long partSize = part.getSize();
                  out.println("<BR>Part Name = "+part.getName());
                  out.println("<BR>Part Header = " + partHeader);
                  out.println("<BR>Part Size = " + partSize);
                  System.out.println("part.getHeader("content-disposition") = " + part.getHeader("content-disposition"));
               }
           out.println("<center><h1>File Upload Completed Successfully</h1></center></body></html>");


           //**** Custom Option ****//
           System.out.println("Custom Way To Upload File with Actual FileName.");
           fileUploadWithDesiredFilePathAndName(request);
           System.out.println("File Uploaded using custom Way.");
        }

    

     /* Following method allows us to place the uploaded file in a desired Location on the server along with the desired fileName */
     public void fileUploadWithDesiredFilePathAndName(HttpServletRequest request) throws IOException,ServletException
        {
          /******** Following part of code is not needed ********/
          InputStream inputStream = null;
          FileOutputStream outputStream =null;
          try
           {
             for (Part part : request.getParts()) 
               {
                  System.out.println(part.getName());
                  inputStream = request.getPart(part.getName()).getInputStream();
                  int i = inputStream.available();
                  byte[] b  = new byte[i];
                  inputStream.read(b);
                  System.out.println("Length : " + b.length);

                // Finding the fileName //
                  String fileName = "";
                  String partHeader = part.getHeader("content-disposition");
                  System.out.println("Part Header = " + partHeader);
                  System.out.println("part.getHeader("content-disposition") = " + part.getHeader("content-disposition"));

                  for (String temp : part.getHeader("content-disposition").split(";")) 
                     {
                       if (temp.trim().startsWith("filename")) 
                        {
                           fileName=temp.substring(temp.indexOf('=') + 1).trim().replace(""", "");
                        }
                     }

                  // Writing contents to desired FilePath & FileName //
                  String uploadDir=System.getProperty("jboss.server.base.dir")+"/upload";
                  System.out.println("File will be Uploaded at: " +uploadDir+"/"+fileName);                  
                  outputStream = new FileOutputStream(uploadDir +"/"+fileName);
                  outputStream.write(b);
                  inputStream.close();
               }
            }
          catch(Exception e)
            {
               System.out.println("Unable to Upload File: "+e);
               e.printStackTrace();
            }
          finally
            {
                if(inputStream!=null)
                   {   
                      try{ inputStream.close(); } catch(Exception e){ e.printStackTrace(); } 
                   }
                if(outputStream!=null)
                   {   
                      try{ outputStream.close(); } catch(Exception e){ e.printStackTrace(); } 
                   }
            }
        }
   }

NOTE:
The above servlet represents two ways to upload the file. One is purely using @MultipartConfig(location=”/home/userone/EE6_FileUpload_Servlet”) in this case the upload file location is specified but the uploaded file will have some random name, which is quite confusing some time.

So the above Servlet also has a separate method “fileUploadWithDesiredFilePathAndName(HttpServletRequest)” which extract the actual file name and places it in a desired location on the server box.

Step5). Now we will write a simple ant “build.xml” file in order to build and deploy our web application on JBoss AS7. So write the following “build.xml” file inside “/home/userone/EE6_FileUpload_Servlet” as following:

<project name="Servlet3FileUploadProject" default="deploy">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.CR1b" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="output.dir" value="build" />
<property name="src.dir" value="src" />
<property name="war.name" value="Servlet3FileUploadDemo.war" />

        <path id="jboss.classpath">
           <fileset dir="${jboss.module.dir}">
              <include name="**/*.jar"/>
           </fileset>  
        </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>
	 
        <target name="build" depends="init">
           <mkdir dir="${tmp.dir}/WEB-INF/classes"/>
           <copy file="${src.dir}/index.jsp" todir="${tmp.dir}"/>
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath"/> 

           <copy todir="${tmp.dir}/WEB-INF">
                <fileset dir="${src.dir}/">
                      <include name="web.xml"/> 
                </fileset>
           </copy>          
           <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
      
           <!-- Clean up -->
           <copy file="${tmp.dir}/${war.name}" tofile="${output.dir}/${war.name}"/>
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}"/>
           </delete> 
        </target>

        <target name="deploy" depends="build">
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />  
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  
        </target>
</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script is to point to your own JBoss AS7 directory home directory.

Step6). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/apache-ant-1.8.2/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/apache-ant-1.8.2/bin;%PATH%

Step7). Now run the ant file from the directory where you have placed the “build.xml” file as following:

[userone@localhost httpOnlyDemo]$ ant

Buildfile: build.xml

init:
   [delete] Deleting directory /home/userone/EE6_FileUpload_Servlet/build
    [mkdir] Created dir: /home/userone/EE6_FileUpload_Servlet/build
    [mkdir] Created dir: /home/userone/EE6_FileUpload_Servlet/tmp

build:
    [mkdir] Created dir: /home/userone/EE6_FileUpload_Servlet/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/EE6_FileUpload_Servlet/tmp
    [javac] Compiling 1 source file to /home/userone/EE6_FileUpload_Servlet/tmp/WEB-INF/classes
      [jar] Building jar: /home/userone/EE6_FileUpload_Servlet/tmp/Servlet3FileUploadDemo.war
     [copy] Copying 1 file to /home/userone/EE6_FileUpload_Servlet/build

deploy:
     [echo] *******************  Deploying the WAR file Servlet3FileUploadDemo.war *********************
     [echo] ********** build/Servlet3FileUploadDemo.war to /home/userone/jboss-as-7.1.0.CR1b/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.CR1b/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

BUILD SUCCESSFUL
Total time: 3 seconds

Step8). Now access the application like following: “http://localhost:8080/Servlet3FileUploadDemo/index.jsp

NOTE: We will need to make sure that whatever upload directory we have choosen for this demo, Must already exist.
.
.
Thanks
MiddlewareMagic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.