How to Upload Binary File to Spring REST Service

JAVA

Introduction

Web services are a great way to create decoupled applications. REST based services are mainly used in current technological trends as they are based on simple HTTP protocol. Passing basic string data to and from a REST based service is quiet straight forward. However there are situations where we need to send/upload a file to a REST based service. In this tutorial we are going to walk-thorough the process of how to upload binary file to Spring REST Service.

How to upload binary file to Spring REST Service?

Here we will be creating a Spring 4.0 based REST service and an HTML client. Further we will test the process by uploading a binary file to the service.

Creating Spring REST Service

Creation of Spring based REST service is simple. We just need to follow following steps:

Step -1: Create a class MyRestService

public class MyRestService { }

Step-2: Now to convert this class to a Spring based REST web service, we need to add few annotations to the class. The first annotation we add is @RestController, it tells the Spring context that current class will act as Spring REST web service.

@RestController
public class MyRestService { }

Step-3: Next we will add an endpoint to this class that will be appended to the base URL of the application.

@RestController
@RequestMapping(value = "/myservice")
public class MyRestService { }

Here the URL to web service MyRestService.java will be <base_URL_of_application>/myservice.

Step-4: As we will be uploading a file to the service we need to configure @MultipartConfig. In web terminology binary data is addressed as Multipart.

@RestController
@RequestMapping(value = "/myservice")
//Max uploaded file size (here it is 20 MB)
@MultipartConfig(fileSizeThreshold = 20971520)
public class MyRestService { }

Here fileSizeThreshold attribute of @MultipartConfig configures the maximum size limit of the file to be uploaded (in bytes).

Step-5: Now we need to create the method that will handle the main work. The work of extracting data from the uploaded file and saving it on the server. For this we simply define a method inside out MyRestService class.

public String uploadFile(){}

Step-6: Now we need to give the URL part of this method. This will be appended to the URL of the class MyRestService.

@RequestMapping(value = "/upload")
public String uploadFile(){}

Here /upload will be appended to the URL of MyRestService. So here the complete URL to be used by client will be <base_URL_of_application>/myservice/upload.

Step-7: Now comes the mapping part. Mapping between the HTML form parameter used in the client with an attribute of uploadFile() method. To do this mapping we use @RequestParam.

@RequestMapping(value = "/upload")
public String uploadFile(@RequestParam("uploadedFile") MultipartFile uploadedFileRef){}

Here the String uploadedFile used as the parameter of @RequestParam is the name of HTML form parameter that is of file type. In the above code snippet uploadedFileRef is the actual reference to the uploaded file.

Step-8: Now that we have created our method and got the reference of the uploaded, rest of the process is easy. We just need to extract the data from uploadedFileRef and write it to a file on the server. This logic is displayed in the code below:

// Get name of uploaded file.
String fileName = uploadedFileRef.getOriginalFilename();

// Path where the uploaded file will be stored.
String path = "D:/" + fileName;

// This buffer will store the data read from 'uploadedFileRef'
byte[] buffer = new byte[1000];

// Now create the output file on the server.
File outputFile = new File(path);

FileInputStream reader = null;
FileOutputStream writer = null;
int totalBytes = 0;
try {
    outputFile.createNewFile();

    // Create the input stream to uploaded file to read data from it.
    reader = (FileInputStream) uploadedFileRef.getInputStream();

    // Create writer for 'outputFile' to write data read from
    // 'uploadedFileRef'
    writer = new FileOutputStream(outputFile);

    // Iteratively read data from 'uploadedFileRef' and write to
    // 'outputFile';            
    int bytesRead = 0;
    while ((bytesRead = reader.read(buffer)) != -1) {
        writer.write(buffer);
        totalBytes += bytesRead;
    }
} catch (IOException e) {
    e.printStackTrace();
}finally{
    try {
        reader.close();
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Creating HTML client

The HTML client is a simple client with only one file component and a submit button:

<form method="POST" enctype="multipart/form-data"
      action="http://localhost:8080/MyProject/myservice/upload">
   File to upload: <input type="file" name="uploadedFile"><br />
   <input type="submit" value="Upload">
</form>

Here the name attribute of file input should have same value as that in the parameter of @RequestParam(uploadedFile) in our service method.

Complete code

Complete code of web service as well as HTML client is shown below:

Web Service

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.servlet.annotation.MultipartConfig;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping(value = "/myservice")
//Max uploaded file size (here it is 20 MB)
@MultipartConfig(fileSizeThreshold = 20971520)
public class MyRestService {

    @RequestMapping(value = "/upload")
    public String uploadFile(
            @RequestParam("uploadedFile") MultipartFile uploadedFileRef) {
    // Get name of uploaded file.
    String fileName = uploadedFileRef.getOriginalFilename();

    // Path where the uploaded file will be stored.
    String path = "D:/" + fileName;

    // This buffer will store the data read from 'uploadedFileRef'
    byte[] buffer = new byte[1000];

    // Now create the output file on the server.
    File outputFile = new File(path);

    FileInputStream reader = null;
    FileOutputStream writer = null;
    int totalBytes = 0;
    try {
        outputFile.createNewFile();

        // Create the input stream to uploaded file to read data from it.
        reader = (FileInputStream) uploadedFileRef.getInputStream();

        // Create writer for 'outputFile' to write data read from
        // 'uploadedFileRef'
        writer = new FileOutputStream(outputFile);

        // Iteratively read data from 'uploadedFileRef' and write to
        // 'outputFile';            
        int bytesRead = 0;
        while ((bytesRead = reader.read(buffer)) != -1) {
            writer.write(buffer);
            totalBytes += bytesRead;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        try {
            reader.close();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

        return "File uploaded successfully! Total Bytes Read="+totalBytes;
    }

}

HTML client

<form method="POST" enctype="multipart/form-data"
      action="http://localhost:8080/MyProject/myservice/upload">
   File to upload: <input type="file" name="uploadedFile"><br />
   <input type="submit" value="Upload">
</form>

Output

Run your web service and open the HTML client in a browser. The client will look like:

Spring HTML client

Spring HTML client

Now select any file using Browse button and hit Upload button. The result should look like:

Spring file upload

Spring file upload