ZetCode

Java Servlet upload file

last modified July 13, 2020

Java Servlet upload file shows how to upload a single file in a Java web application using servlet technology.

Java Servlet

Servlet is a Java class which responds to a particular type of network request - most commonly an HTTP request. Java servlets are used to create web applications. They run in servlet containers such as Tomcat or Jetty. Modern-day Java web development uses frameworks that are built on top of servlets.

HTML form encoding types

There are three encoding HTML form methods for a POST request:

The application/x-www-form-urlencoded is the default encoding. The values are encoded in key-value tuples separated by &. The = character is used between the key and the value. Non-alphanumeric characters are percent encoded. This encoding type is not suitable for binary files.

The multipart/form-data is used for non-acsii data and binary files. The input element's type attribute is set to file.

The text/plain is used for debugging.

Java Servlet upload file example

In the following application, we have a web form to select a file to be uploaded to the server. The form calls a Java servlet, which reads the file and saves it into the directory.

Upload directory

The /var/www directory is a standard directory for web content in Debian Linux.

$ ls -ld /var/www/upload/
drwxrwxr-x 2 www-data www-data 4096 Dec  3 14:29 /var/www/upload/

We are going to upload files to the /var/www/upload directory. The directory files can be modified by users who are in the www-data group. So the user who runs the web server must be in this group.

Application

This is a Maven web application; it is deployed on Tomcat.

$ tree
.
├── nb-configuration.xml
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── zetcode
        │           └── FileUploadServlet.java
        └── webapp
            ├── index.html
            └── META-INF
                └── context.xml

This is the project structure.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>JavaServletFileUploadEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>JavaServletFileUploadEx</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

This is the Maven POM file. The javax.servlet-api artifact is for servlets. The maven-war-plugin is responsible for collecting all artifact dependencies, classes and resources of the web application and packaging them into a web application archive (WAR).

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JavaServletFileUploadEx"/>

In the Tomcat context.xml file, we define the context path. It is the name of the web application.

com/zetcode/FileUploadServlet.java
package com.zetcode;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet(name = "FileUploadServlet", urlPatterns = {"/FileUploadServlet"},
      initParams = { @WebInitParam(name = "path", value = "/var/www/upload/") })
@MultipartConfig
public class FileUploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
            
        response.setContentType("text/plain;charset=UTF-8");    

        ServletOutputStream os = response.getOutputStream();

        ServletConfig sc = getServletConfig();
        String path = sc.getInitParameter("uploadpath");

        Part filePart = request.getPart("myfile");

        String fileName = filePart.getSubmittedFileName(); 
        InputStream is = filePart.getInputStream();

        Files.copy(is, Paths.get(path + fileName),
                StandardCopyOption.REPLACE_EXISTING);

        os.print("File successfully uploaded");
    }
}

The FileUploadServlet uploads a file to the /var/www/upload directory.

@WebServlet(name = "FileUploadServlet", urlPatterns = {"/FileUploadServlet"},
     initParams = { @WebInitParam(name = "uploadpath", value = "/var/www/upload/") })

With the @WebServlet annotation, we map the servlet to the /FileUploadServlet URL pattern and define an initial uploadpath variable.

@MultipartConfig

The servlet is also decorated with @MultipartConfig. The @MultipartConfig annotation indicates that the servlet expects requests to be made using the multipart/form-data MIME type.

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {

POST requests are handled by the doPost method.

ServletOutputStream os = response.getOutputStream();

We get the servlet output stream with getOutputStream method.

ServletConfig sc = getServletConfig();
String path = sc.getInitParameter("uploadpath");

We retrieve the initial parameter. It is the directory where we are going to upload a file.

Part filePart = request.getPart("myfile");

The file part is retrieved with the getPart method.

String fileName = filePart.getSubmittedFileName(); 
InputStream is = filePart.getInputStream();

We get the part's file name and input stream.

Files.copy(is, Paths.get(path + fileName),
        StandardCopyOption.REPLACE_EXISTING);

With Files.copy, we copy the file to the destination directory.

os.print("File successfully uploaded");

In the end, we write a message back to the client.

index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Uploading a file</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css">
    </head>
    <body>
        <form class="pure-form pure-form-stacked" method="post" action="FileUploadServlet" 
              enctype="multipart/form-data">
            <fieldset>
                <legend>File:</legend>
                <input type="file" name="myfile">
                <button type="submit" class="pure-button pure-button-primary">Upload</button>
            </fieldset>
        </form>
    </body>
</html>

This is the home page to select a file to be uploaded. It contains an HTML form. Upon submitting the form, the processing is sent to the FileUploadServlet.

<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css">

We include the Pure.css library for creating responsible pages.

<form class="pure-form pure-form-stacked" method="post" action="FileUploadServlet" 
        enctype="multipart/form-data">

The method attribute is post, because we send data to the server. The action attribute specifies the name of the servlet, which processes the request. The enctype attribute specifies the multipart/form-data encoding type, which is required for uploading a file with an HTML form.

<input type="file" name="myfile">

The type attribute of the input tag lets a user choose a single file.

<button type="submit" class="pure-button pure-button-primary">Upload</button>

This is the Submit button.

In this tutorial, we have shown how to upload a single file with a Java servlet.