Tutorial

Servlet Upload File and Download File Example

Published on August 3, 2022
author

Pankaj

Servlet Upload File and Download File Example

Servlet Upload File and Download File is a common task in java web application. Since I have written a lot about java servlet recently, I thought to provide a sample example of servlet file upload to server and then download from server to client.

Servlet Upload File

Our use case is to provide a simple HTML page where client can select a local file to be uploaded to server. On submission of request to upload the file, our servlet program will upload the file into a directory in the server and then provide the URL through which user can download the file. For security reason, user will not be provided direct URL for downloading the file, rather they will be given a link to download the file and our servlet will process the request and send the file to user. We will create a dynamic web project in Eclipse and the project structure will look like below image. Servlet Upload File, java upload file to server, servlet download file Let’s look into all the components of our web application and understand the implementation.

HTML Page for Java Uploading File to Server

We can upload a file to server by sending a post request to servlet and submitting the form. We can’t use GET method for uploading file. Another point to note is that enctype of form should be multipart/form-data. To select a file from user file system, we need to use input element with type as file. So we can have a simple HTML page index.html for uploading file as:

<html>
<head></head>
<body>
<form action="UploadDownloadFileServlet" method="post" enctype="multipart/form-data">
Select File to Upload:<input type="file" name="fileName">
<br>
<input type="submit" value="Upload">
</form>
</body>
</html>

Server File Location for File Upload

We need to store file into some directory at server, we can have this directory hardcoded in program but for better flexibility, we will keep it configurable in deployment descriptor context params. Also we will add our upload file html page to the welcome file list. Our web.xml file will look like below:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>ServletFileUploadDownloadExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>tempfile.dir</param-name>
    <param-value>tmpfiles</param-value>
  </context-param>
</web-app>

ServletContextListener for File Upload Location

Since we need to read context parameter for file location and create a File object from it, we can write a ServletContextListener to do it when context is initialized. We can set absolute directory location and File object as context attribute to be used by other servlets. Our ServletContextListener implementation code is like below.

package com.journaldev.servlet;

import java.io.File;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class FileLocationContextListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent servletContextEvent) {
    	String rootPath = System.getProperty("catalina.home");
    	ServletContext ctx = servletContextEvent.getServletContext();
    	String relativePath = ctx.getInitParameter("tempfile.dir");
    	File file = new File(rootPath + File.separator + relativePath);
    	if(!file.exists()) file.mkdirs();
    	System.out.println("File Directory created to be used for storing files");
    	ctx.setAttribute("FILES_DIR_FILE", file);
    	ctx.setAttribute("FILES_DIR", rootPath + File.separator + relativePath);
    }

	public void contextDestroyed(ServletContextEvent servletContextEvent) {
		//do cleanup if needed
	}
	
}

File Upload Download Servlet

Update: Servlet Specs 3 added support to upload files on server in the API, so we won’t need to use any third party API. Please check out Servlet 3 Upload File. For File upload, we will use Apache Commons FileUpload utility, for our project we are using version 1.3, FileUpload depends on Apache Commons IO jar, so we need to place both in the lib directory of the project, as you can see that in above image for project structure. We will use DiskFileItemFactory factory that provides a method to parse the HttpServletRequest object and return list of FileItem. FileItem provides useful method to get the file name, field name in form, size and content type details of the file that needs to be uploaded. To write file to a directory, all we need to do it create a File object and pass it as argument to FileItem write() method. Since the whole purpose of the servlet is to upload file, we will override init() method to initialise the DiskFileItemFactory object instance of the servlet. We will use this object in the doPost() method implementation to upload file to server directory. Once the file gets uploaded successfully, we will send response to client with URL to download the file, since HTML links use GET method,we will append the parameter for file name in the URL and we can utilise the same servlet doGet() method to implement file download process. For implementing download file servlet, first we will open the InputStream for the file and use ServletContext.getMimeType() method to get the MIME type of the file and set it as response content type. We will also need to set the response content length as length of the file. To make sure that client understand that we are sending file in response, we need to set “Content-Disposition” header with value as "attachment; filename=“fileName”. Once we are done with setting response configuration, we can read file content from InputStream and write it to ServletOutputStream and the flush the output to client. Our final implementation of UploadDownloadFileServlet servlet looks like below.

package com.journaldev.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/UploadDownloadFileServlet")
public class UploadDownloadFileServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private ServletFileUpload uploader = null;
	@Override
	public void init() throws ServletException{
		DiskFileItemFactory fileFactory = new DiskFileItemFactory();
		File filesDir = (File) getServletContext().getAttribute("FILES_DIR_FILE");
		fileFactory.setRepository(filesDir);
		this.uploader = new ServletFileUpload(fileFactory);
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String fileName = request.getParameter("fileName");
		if(fileName == null || fileName.equals("")){
			throw new ServletException("File Name can't be null or empty");
		}
		File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
		if(!file.exists()){
			throw new ServletException("File doesn't exists on server.");
		}
		System.out.println("File location on server::"+file.getAbsolutePath());
		ServletContext ctx = getServletContext();
		InputStream fis = new FileInputStream(file);
		String mimeType = ctx.getMimeType(file.getAbsolutePath());
		response.setContentType(mimeType != null? mimeType:"application/octet-stream");
		response.setContentLength((int) file.length());
		response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
		
		ServletOutputStream os = response.getOutputStream();
		byte[] bufferData = new byte[1024];
		int read=0;
		while((read = fis.read(bufferData))!= -1){
			os.write(bufferData, 0, read);
		}
		os.flush();
		os.close();
		fis.close();
		System.out.println("File downloaded at client successfully");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if(!ServletFileUpload.isMultipartContent(request)){
			throw new ServletException("Content type is not multipart/form-data");
		}
		
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.write("<html><head></head><body>");
		try {
			List<FileItem> fileItemsList = uploader.parseRequest(request);
			Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
			while(fileItemsIterator.hasNext()){
				FileItem fileItem = fileItemsIterator.next();
				System.out.println("FieldName="+fileItem.getFieldName());
				System.out.println("FileName="+fileItem.getName());
				System.out.println("ContentType="+fileItem.getContentType());
				System.out.println("Size in bytes="+fileItem.getSize());
				
				File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileItem.getName());
				System.out.println("Absolute Path at server="+file.getAbsolutePath());
				fileItem.write(file);
				out.write("File "+fileItem.getName()+ " uploaded successfully.");
				out.write("<br>");
				out.write("<a href=\"UploadDownloadFileServlet?fileName="+fileItem.getName()+"\">Download "+fileItem.getName()+"</a>");
			}
		} catch (FileUploadException e) {
			out.write("Exception in uploading file.");
		} catch (Exception e) {
			out.write("Exception in uploading file.");
		}
		out.write("</body></html>");
	}

}

The sample execution of the project is shown in below images. Servlet File Upload HTML JSP Form Servlet File Upload to Server Servlet Download File

Download Servlet File Upload Download Project

You can download Apache Commons IO jar and Apache Commons FileUpload jar from below URLs. https://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi https://commons.apache.org/proper/commons-io/download_io.cgi

Download Servlet File Upload Download Example Project

Check out next article in the series about Servlet Exception Handling.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
November 2, 2013

sometimes on downloading file on client side, servlet gives content length -1 but file keeps on downloading. Any suggestions?

- pralabh

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    November 17, 2013

    I have tried this example the upload part is fine. But the while downloading the file is always saved as UploadDownloadFileServlet with no extension so the file is not readable. Any suggestion … ? Ex when I click on Download “books.pdf” it saved as UploadDownloadFileServlet

    - Devendra

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      January 6, 2014

      i am create java website in eclipse, sql server 2008 r2 for database for servlet to database i use type 4 connectivity by using sql_jdbc 4 driver but they show me com.microsoft.sqlserver.jdbc.sqlserverexception but ping was succeed…what i do please help me

      - ganesh

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        January 27, 2014

        hi i want help me for upload files with details information after that send data to database with information bellow by JSP like (File_ID, File_name, File_Description,Date_file, Upload_file) if any persons help me

        - zanyar

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          March 4, 2014

          hi i want to upload images by creating folder with username and upload image to username folder for every user like that.

          - msaahish

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            March 4, 2014

            it showing an error-----import javax.servlet.annotation.WebListener; (cannot be resolved). @WebListener (cannot be resolved a type)

            - Hareesh

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              March 17, 2014

              erro getServletContext() ???

              - ana

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                March 18, 2014

                Hello i am sonerao and very thank You for sharing this File upload Code it very Help full. But at the time of code importing is giving some error. i’m download u r .zip file and this file i import as it is into my eclipse it will be import success fully but it will give an error at the time of Project Deployment i have a app-ache tomcat 6.0. So Can u Give some Conclusion .thank You

                - Sonerao JAdhav

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  March 26, 2014

                  Sir if i m using glassfish then servlet is not found error is reflected can u help me in this is it mandatory to use glassfish?

                  - Diksha

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    April 2, 2014

                    Im gettin g this error when i browse for a file and click upload. Pls help me asap. Im just trying to upload a jar file(tightvnc-jviewer.jar). Im not able to upload any type of file. It gives me the same exception everytime. Absolute Path at server=D:\Sanjay\Softwares\apache-tomcat-7.0.53\apache-tomcat-7.0.53\tmpfiles\D:\Sanjay\Softwares\tightvnc-jviewer.jar java.io.FileNotFoundException: D:\Sanjay\Softwares\apache-tomcat-7.0.53\apache-tomcat-7.0.53\tmpfiles\D:\Sanjay\Softwares\tightvnc-jviewer.jar (The filename, directory name, or volume label syntax is incorrect) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.(FileOutputStream.java:179) at java.io.FileOutputStream.(FileOutputStream.java:131) at org.apache.commons.fileupload.disk.DiskFileItem.write(DiskFileItem.java:417) at com.journaldev.servlet.UploadDownloadFileServlet.doPost(UploadDownloadFileServlet.java:85) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)

                    - Sanjay

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Become a contributor for community

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      DigitalOcean Documentation

                      Full documentation for every DigitalOcean product.

                      Resources for startups and SMBs

                      The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                      Get our newsletter

                      Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                      New accounts only. By submitting your email you agree to our Privacy Policy

                      The developer cloud

                      Scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Get started for free

                      Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                      *This promotional offer applies to new accounts only.