Tuesday, July 27, 2021

File Upload Example in Java using Servlet, JSP and Apache Commons FileUpload - Tutorial

Uploading Files to the server using Servlet and JSP is a common task in Java web applications. Before coding your Servlet or JSP to handle file upload requests, you need to know a little bit about File upload support in HTML and HTTP protocol. If you want your user to choose files from the file system and upload them to the server then you need to use <input type="file"/>. This will enable us to choose any file from the file system and upload to a server. 

The next thing is that the form method should be HTTP POST with enctype as multipart/form-data, which makes file data available in parts inside the request body. Now in order to read those file parts and create a File inside Servlet can be done by using ServletOutputStream.

Though, It's better to use Apache Commons FileUpload, an open-source library. Apache FileUpload handles all low details of parsing HTTP requests which conform to RFC 1867 or "Form-based File Upload in HTML” when you set form method post and content type as "multipart/form-data".

 

Apache Commons FileUpload - Important points:

1) DiskFileItemFactory is the default Factory class for FileItem. When Apache commons read multipart content and generate FileItem, this implementation keeps file content either in memory or in the disk as a temporary file, depending upon threshold size.

By default, DiskFileItemFactory has a threshold size of 10KB and generates temporary files in the temp directory, returned by System.getProperty("java.io.tmpdir")

Both of these values are configurable and it's best to configure these for production usage. You may get permission issues if the user account used for running the Server doesn't have sufficient permission to write files into the temp directory.



2) Choose threshold size carefully based upon memory usage, keeping large content in memory may result in java.lang.OutOfMemory, while having too small values may result in lot's of temporary files.

3) Apache commons file upload also provides FileCleaningTracker for deleting temporary files created by DiskFileItemFactory. FileCleaningTracker deletes temporary files as soon as the corresponding File instance is garbage collected. It accomplishes this by a cleaner thread which is created when FileCleaner is loaded. If you use this feature, then remember to terminate this Thread when your web application ends.

4) Keep configurable details e.g. upload directory, maximum file size, threshold size etc in config files and use reasonable default values in case they are not configured.

5) It's good to validate size, type, and other details of Files based upon your project requirement e.g. you may want to allow upload only images of a certain size and certain types e.g. JPEG, PNG, etc.

File Upload Example in Java Servlet and JSP

Here is the complete code for uploading files in Java web application using Servlet and JSP. This File Upload Example needs four files :
1. index.jsp which contains HTML content to set up a form, which allows the user to select and upload a file to the server.

2. FileUploader Servlet which handles file upload request and uses Apache FileUpload library to parse multipart form data

3. web.xml to configure servlet and JSP in Java web application.

4. result.jsp for showing the result of the file upload operation.



FileUploadHandler.java

import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet to handle File upload request from Client
 * @author Javin Paul
 */
public class FileUploadHandler extends HttpServlet {
    private final String UPLOAD_DIRECTORY = "C:/uploads";
  
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
      
        //process only if its multipart content
        if(ServletFileUpload.isMultipartContent(request)){
            try {
                List<FileItem> multiparts = new ServletFileUpload(
                                         new DiskFileItemFactory()).parseRequest(request);
              
                for(FileItem item : multiparts){
                    if(!item.isFormField()){
                        String name = new File(item.getName()).getName();
                        item.write( new File(UPLOAD_DIRECTORY + File.separator + name));
                    }
                }
           
               //File uploaded successfully
               request.setAttribute("message", "File Uploaded Successfully");
            } catch (Exception ex) {
               request.setAttribute("message", "File Upload Failed due to " + ex);
            }          
         
        }else{
            request.setAttribute("message",
                                 "Sorry this Servlet only handles file upload request");
        }
    
        request.getRequestDispatcher("/result.jsp").forward(request, response);
     
    }
  
}

Java file upload example in JSP Servlet application

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>File Upload Example in JSP and Servlet - Java web application</title>
    </head>
 
    <body> 
        <div>
            <h3> Choose File to Upload in Server </h3>
            <form action="upload" method="post" enctype="multipart/form-data">
                <input type="file" name="file" />
                <input type="submit" value="upload" />
            </form>          
        </div>
      
    </body>
</html>

result.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>File Upload Example in JSP and Servlet - Java web application</title>
    </head>
 
    <body> 
        <div id="result">
            <h3>${requestScope["message"]}</h3>
        </div>
      
    </body>
</html>


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

   <servlet>
        <servlet-name>FileUploadHandler</servlet-name>
        <servlet-class>FileUploadHandler</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FileUploadHandler</servlet-name>
        <url-pattern>/upload</url-pattern>
    </servlet-mapping>
  
  
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>


In summary, just keep three things in mind while uploading files using Java web application
1) Use HTML form input type as File to browse files to upload
2) Use form method as post and enctype as multipart/form-data
3) Use Apache commons FileUpload in Servlet to handle HTTP requests with multipart data.

Dependency

In order to compile and run this Java web application in any web server e.g. Tomcat, you need to include following dependency JAR in the WEB-INF lib folder.

commons-fileupload-1.2.2.jar
commons-io-2.4.jar

If you are using Maven then you can also use following dependencies :
<dependency>
     <groupId>commons-fileupload</groupId>
     <artifactId>commons-fileupload</artifactId>
     <version>1.2.2</version>
</dependency>
<dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.4</version>
</dependency>


That's all on How to Upload Files using Servlet and JSP in Java web application. This File Upload example can be written using JSP, Filter or Servlet because all three are request’s entry points in Java web application. I have used Servlet for handling File upload request for simplicity. By the way from Servlet 3.0 API, Servlet is supporting multipart form data and you can use the getPart() method of HttpServletRequest to handle file upload.


20 comments :

Anonymous said...

Can I upload an image by using this way? Thanks!

Anonymous said...

upon execution of the above code i am encountering a 404 error after clicking on upload. what to do?

Anonymous said...

Hi... its functioning well but there is a problem in that images also gets saved in classes folder with other class files... it makes the war file toooo heavy to deploy

Syed Rizwan said...

Try this :

Before coding download the package : cos.jar

First create a HTML file and upload.jsp

upload.jsp : Add the given below:

import="com.oreilly.servlet.MultipartRequest"

MultipartRequest m = new MultipartRequest(request,"e:/syed",10590378);

out.println("Uploaded");


Unknown said...

stp , c'est que cette erreur :
File Upload Failed due to java.lang.ClassCastException: org.netbeans.modules.web.monitor.server.MonitorRequestWrapper cannot be cast to org.apache.tomcat.util.http.fileupload.RequestContext


le code est:
List multiparts = new ServletFileUpload(
new DiskFileItemFactory()).parseRequest(request);

mais il affiche une erreur et m'a obliger a corriger l'erreur comme ca :
List multiparts = new ServletFileUpload(
new DiskFileItemFactory()).parseRequest((RequestContext) request);

Anonymous said...

Hello ! :)
I'm trying to get this upload thing to work for 3 hours now, i'm getting crazy !
Your example seemed very good so I copied it aaaaaand it doesn't work :(
I'm getting the message "File Uploaded Successfully" but there's no file where it should...
I've found out that the issue is with the line :

List multiparts = new ServletFileUpload( new DiskFileItemFactory()).parseRequest(request);

My list is empty...

I hope that you, or someone else, can help me !

Thanks :)
William

Anonymous said...

Nevermind, I've found the solution !
For those it might concern :
The problem was with the line
"< input type="file" name="file" />"
I didn't have the "name" field, but an "id" field instead. Silly !

So, thank you very much for your working example ! ;)
William

Unknown said...

Hi, i used above mentioned code to upload a file and also placed jar file at corresponding path. but i am getting error..

package does not exist..

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

pls assist to resolve it.

Anonymous said...

how to get the attachment if it located at other server. it is only can retrieve from same server only ?

+plain-jane said...

any ideas how to do it if my destination location is sftp server? thanks~

Anonymous said...

Type Safety Error: List needs Unchecked Conversion to confirm List
Please help me to solve this error

Nitish Chitranshi said...

I have used the above code. It is working fine if I run it on the Server installed on windows platform, but while executing this on the Unix server, the image is not getting uploaded. Can you please tell me how to upload the image in the unix server?

javin paul said...

@Nitish, this is Java code and it's using Java library, so its supposed to work on both Windows and Linux. Can you please tell us more about the issue? are you getting any exception on Linux? What exactly means you are not able to upload images?

Anonymous said...

Hi, i used above mentioned code to upload a file and also placed jar file at corresponding path. but i am getting error..

error is :
http 505 sevlet class not found

Unknown said...

Great work...

Unknown said...

i want make name for uploading file.pls help me.

Anonymous said...

request.getRequestDispatcher("/result.jsp").include(request, response); does not redirect to the jsp page.

What should I do if I want this to be redirected to another page?

Vaibhav Shrivastav said...

Hi , When i get file in spring rest API using Multi-part. I am not storing file on tomcat server . But why is store in my tomcat server root directory by default. Please give me solutions and do want to store file on server. Please help me

javin paul said...

Hello @Vaibhav, Your server must be using default location for storing uploaded file. If you want to store file somewhere else, just look for that option in Tomcat. Where exactly you want to store your files?

Ahamed said...

Hi Paul,

I am facing an issue, where in local eclipse workspace everything is working fine upload by creating a temporary file. But when the code is moved to the next environment like Sit or aws, the fileitem list is coming empty in both the servers......


In local I'm using Apache Tomcat Server and eclipse version neon..

Do I need to take any permission to create temporary files in server... If yes how can I inform the server


Pls help....

Post a Comment