Java Rest Upload File Example

Spring Boot 2 - File Upload and Download Rest API Tutorial


In this tutorial, we will learn how to upload and download a file using Spring Boot RESTful API.  Uploading and downloading files are very common tasks for which developers need to write code in their applications.

Learn and master in Spring boot at Spring Boot Tutorial

We'll first build the REST APIs for uploading and downloading files, and then test those APIs using Postman.

Let's get started.

Video Tutorial

This tutorial is explained with demo in below YouTube video. Subscribe to my youtube channel for future video updates at https://www.youtube.com/c/javaguides.

Table of Contents

  1. Tools and Technologies Used
  2. Create and Import Spring Boot Project
  3. Project Directory Structure
  4. The pom.xml File
  5. Configuring Server and File Storage Properties
  6. Automatically binding properties to a POJO class
  7. Writing APIs for File Upload and Download
  8. Service for Storing Files in the FileSystem and retrieving them
  9. Custom Exception Classes
  10. Running the Application and Testing the APIs via Postman

1. Tools and Technologies Used

  • Spring Boot - 2.1.0.RELEASE
  • JDK - 1.8 or later
  • Spring Framework - 5.1.2 RELEASE
  • Maven - 3.2+
  • IDE - Eclipse or Spring Tool Suite (STS)

2. Create and Import Spring Boot Project

Let'specify the following details:

  • Generate: Maven Project
  • Java Version: 1.8 (Default)
  • Spring Boot:2.1.0
  • Group: net.javaguides.springboot
  • Artifact: springboot-upload-download-file-rest-api-example
  • Name: sspringboot-upload-download-file-rest-api-example
  • Description: springboot-upload-download-file-rest-api-example
  • Package Name : net.guides.springboot.springbootfileupload
  • Packaging: jar (This is the default value)
  • Dependencies: Web

Once, all the details are entered, click on Generate Project button will generate a spring boot project then download it. That's it! You may now unzip the downloaded application archive and import it into your favorite IDE.

3. Project Directory Structure

Below, the diagram shows a project structure for reference:

4. The pom.xml File

<?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>net.javaguides.springboot</groupId>     <artifactId>springboot-upload-download-file-rest-api-example</artifactId>     <version>0.0.1-SNAPSHOT</version>     <packaging>jar</packaging>     <name>springboot-upload-download-file-rest-api-example</name>     <description>Demo project for Spring Boot</description>     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.1.0.RELEASE</version>         <relativePath/>                                      <!--                    lookup parent from repository                    -->                                    </parent>     <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>         <java.version>1.8</java.version>     </properties>     <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <scope>test</scope>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-configuration-processor</artifactId>             <optional>true</optional>         </dependency>     </dependencies>     <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build> </project>

5. Configuring Server and File Storage Properties

Let's configure our Spring Boot application to enable Multipart file uploads, and define the maximum file size that can be uploaded. We'll also configure the directory into which all the uploaded files will be stored.

Open src/main/resources/application.properties file, and add the following properties to it -

                                      ## MULTIPART (MultipartProperties)                                      #                    Enable multipart uploads                  spring.servlet.multipart.enabled=true                                      #                    Threshold after which files are written to disk.                  spring.servlet.multipart.file-size-threshold=2KB                                      #                    Max file size.                  spring.servlet.multipart.max-file-size=200MB                                      #                    Max Request Size                  spring.servlet.multipart.max-request-size=215MB                                      ## File Storage Properties                  file.upload-dir=./uploads                  server.port=8081

6. Automatically binding properties to a POJO class

Spring Boot has an awesome feature called @ConfigurationProperties using which you can automatically bind the properties defined in the application.properties file to a POJO class.

Let's define a POJO class called FileStorageProperties inside net.javaguides.springboot.fileuploaddownload package to bind all the file storage properties -

                  package                  net.javaguides.springboot.fileuploaddownload.property;                  import                  org.springframework.boot.context.properties.ConfigurationProperties;                  import                  org.springframework.stereotype.Component;                  @Component                  @ConfigurationProperties(prefix                  =                                      "file"                  )                  public                  class                  FileStorageProperties                  {                  private                  String                  uploadDir;                  public                  String                  getUploadDir() {                  return                  uploadDir;     }                  public                  void                  setUploadDir(String                  uploadDir) {                  this                  .uploadDir                  =                  uploadDir;     } }

7. Writing APIs for File Upload and Download

File Upload Rest API

Let's now write the REST APIs for uploading single as well as multiple files. Create a new controller class called FileUploadController inside net.javaguides.springboot.fileuploaddownload.controller package and add following code to it -

                  package                  net.javaguides.springboot.fileuploaddownload.controller;                  import                  java.util.Arrays;                  import                  java.util.List;                  import                  java.util.stream.Collectors;                  import                  org.springframework.beans.factory.annotation.Autowired;                  import                  org.springframework.web.bind.annotation.PostMapping;                  import                  org.springframework.web.bind.annotation.RequestParam;                  import                  org.springframework.web.bind.annotation.RestController;                  import                  org.springframework.web.multipart.MultipartFile;                  import                  org.springframework.web.servlet.support.ServletUriComponentsBuilder;                  import                  net.javaguides.springboot.fileuploaddownload.payload.Response;                  import                  net.javaguides.springboot.fileuploaddownload.service.FileStorageService;                  @RestController                  public                  class                  FileUploadController                  {                  @Autowired                  private                  FileStorageService                  fileStorageService;                  @PostMapping(                    "/uploadFile"                  )                  public                  Response                  uploadFile(@RequestParam(                    "file"                  )                  MultipartFile                  file) {                  String                  fileName                  =                  fileStorageService.storeFile(file);                  String                  fileDownloadUri                  =                  ServletUriComponentsBuilder                  .fromCurrentContextPath()             .path(                    "/downloadFile/"                  )             .path(fileName)             .toUriString();                  return                  new                  Response(fileName, fileDownloadUri,             file.getContentType(), file.getSize());     }                  @PostMapping(                    "/uploadMultipleFiles"                  )                  public                  List                  <                  Response                  >                  uploadMultipleFiles(@RequestParam(                    "files"                  )                  MultipartFile[]                  files) {                  return                  Arrays                  .asList(files)             .stream()             .map(file                  -                  >                  uploadFile(file))             .collect(Collectors                  .toList());     } }

File Download Rest API

Let's now write the REST API for downloading a file. Create a new controller class called FileDownloadController inside net.javaguides.springboot.fileuploaddownload.controller package and add following code to it -

                package                net.javaguides.springboot.fileuploaddownload.controller;                import                java.io.IOException;                import                javax.servlet.http.HttpServletRequest;                import                org.slf4j.Logger;                import                org.slf4j.LoggerFactory;                import                org.springframework.beans.factory.annotation.Autowired;                import                org.springframework.core.io.Resource;                import                org.springframework.http.HttpHeaders;                import                org.springframework.http.MediaType;                import                org.springframework.http.ResponseEntity;                import                org.springframework.web.bind.annotation.GetMapping;                import                org.springframework.web.bind.annotation.PathVariable;                import                org.springframework.web.bind.annotation.RestController;                import                net.javaguides.springboot.fileuploaddownload.service.FileStorageService;                @RestController                public                class                FileDownloadController                {                private                static                final                Logger                logger                =                LoggerFactory                .getLogger(FileDownloadController                .class);                @Autowired                private                FileStorageService                fileStorageService;                @GetMapping(                  "/downloadFile/{fileName:.+}"                )                public                ResponseEntity                <                Resource                >                downloadFile(@PathVariable                String                fileName,                HttpServletRequest                request) {                                  //                  Load file as Resource                Resource                resource                =                fileStorageService.loadFileAsResource(fileName);                                  //                  Try to determine file's content type                String                contentType                =                null;                try                {             contentType                =                request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());         }                catch                (IOException                ex) {             logger.info(                  "Could not determine file type."                );         }                                  //                  Fallback to the default content type if type could not be determined                if                (contentType                ==                null) {             contentType                =                                  "application/octet-stream"                ;         }                return                ResponseEntity                .ok()             .contentType(MediaType                .parseMediaType(contentType))             .header(HttpHeaders                                  .CONTENT_DISPOSITION,                                  "attachment; filename=\"                  "                                +                resource.getFilename()                +                                  "                  \"                  "                )             .body(resource);     } }

Response

This Response class used to return response from the /uploadFile and /uploadMultipleFiles APIs.

Create Response class inside net.javaguides.springboot.fileuploaddownload.payload package with the following contents -

                public                class                Response                {                private                String                fileName;                private                String                fileDownloadUri;                private                String                fileType;                private                long                size;                public                Response(String                fileName,                String                fileDownloadUri,                String                fileType,                long                size) {                this                .fileName                =                fileName;                this                .fileDownloadUri                =                fileDownloadUri;                this                .fileType                =                fileType;                this                .size                =                size;     }                                  //                  Getters and Setters (Omitted for brevity)                }

8. Service for Storing Files in the FileSystem and retrieving them

Let's now write the service for storing files in the file system and retrieving them. Create a new class called FileStorageService.java inside net.javaguides.springboot.fileuploaddownload.service with the following contents -

                  package                  net.javaguides.springboot.fileuploaddownload.service;                  import                  java.io.IOException;                  import                  java.net.MalformedURLException;                  import                  java.nio.file.Files;                  import                  java.nio.file.Path;                  import                  java.nio.file.Paths;                  import                  java.nio.file.StandardCopyOption;                  import                  org.springframework.beans.factory.annotation.Autowired;                  import                  org.springframework.core.io.Resource;                  import                  org.springframework.core.io.UrlResource;                  import                  org.springframework.stereotype.Service;                  import                  org.springframework.util.StringUtils;                  import                  org.springframework.web.multipart.MultipartFile;                  import                  net.javaguides.springboot.fileuploaddownload.exception.FileStorageException;                  import                  net.javaguides.springboot.fileuploaddownload.exception.FileNotFoundException;                  import                  net.javaguides.springboot.fileuploaddownload.property.FileStorageProperties;                  @Service                  public                  class                  FileStorageService                  {                  private                  final                  Path                  fileStorageLocation;                  @Autowired                  public                  FileStorageService(FileStorageProperties                  fileStorageProperties) {                  this                  .fileStorageLocation                  =                  Paths                  .get(fileStorageProperties.getUploadDir())             .toAbsolutePath().normalize();                  try                  {                  Files                  .createDirectories(this                  .fileStorageLocation);         }                  catch                  (Exception                  ex) {                  throw                  new                  FileStorageException(                    "Could not create the directory where the uploaded files will be stored."                  , ex);         }     }                  public                  String                  storeFile(MultipartFile                  file) {                                      //                    Normalize file name                  String                  fileName                  =                  StringUtils                  .cleanPath(file.getOriginalFilename());                  try                  {                                      //                    Check if the file's name contains invalid characters                  if                  (fileName.contains(                    ".."                  )) {                  throw                  new                  FileStorageException(                    "Sorry! Filename contains invalid path sequence                    "                                    +                  fileName);             }                                      //                    Copy file to the target location (Replacing existing file with the same name)                  Path                  targetLocation                  =                  this                  .fileStorageLocation.resolve(fileName);                  Files                  .copy(file.getInputStream(), targetLocation,                  StandardCopyOption                                      .REPLACE_EXISTING);                  return                  fileName;         }                  catch                  (IOException                  ex) {                  throw                  new                  FileStorageException(                    "Could not store file                    "                                    +                  fileName                  +                                      ". Please try again!"                  , ex);         }     }                  public                  Resource                  loadFileAsResource(String                  fileName) {                  try                  {                  Path                  filePath                  =                  this                  .fileStorageLocation.resolve(fileName).normalize();                  Resource                  resource                  =                  new                  UrlResource(filePath.toUri());                  if                  (resource.exists()) {                  return                  resource;             }                  else                  {                  throw                  new                  FileNotFoundException(                    "File not found                    "                                    +                  fileName);             }         }                  catch                  (MalformedURLException                  ex) {                  throw                  new                  FileNotFoundException(                    "File not found                    "                                    +                  fileName, ex);         }     } }

9. Custom Exception Classes

The FileStorageService class throws some exceptions in case of unexpected situations. Following are the definitions of those exception classes (All the exception classes go inside the package net.javaguides.springboot.fileuploaddownload.exception).

FileNotFoundException

                  package                  net.javaguides.springboot.fileuploaddownload.exception;                  import                  org.springframework.http.HttpStatus;                  import                  org.springframework.web.bind.annotation.ResponseStatus;                  @ResponseStatus(HttpStatus                                      .NOT_FOUND)                  public                  class                  FileNotFoundException                  extends                  RuntimeException                  {                  private                  static                  final                  long                  serialVersionUID                  =                  1                  L;                  public                  FileNotFoundException(String                  message) {                  super(message);     }                  public                  FileNotFoundException(String                  message,                  Throwable                  cause) {                  super(message, cause);     } }

FileStorageException

                  package                  net.javaguides.springboot.fileuploaddownload.exception;                  public                  class                  FileStorageException                  extends                  RuntimeException                  {                  private                  static                  final                  long                  serialVersionUID                  =                  1                  L;                  public                  FileStorageException(String                  message) {                  super(message);     }                  public                  FileStorageException(String                  message,                  Throwable                  cause) {                  super(message, cause);     } }
To know more about exception handling in Spring boot then check out Spring Boot 2 Exception Handling for REST APIs

Note that, we've annotated the above exception class with @ResponseStatus(HttpStatus.NOT_FOUND). This ensures that Spring boot responds with a 404 Not Found status when this exception is thrown.

10. Running the Application and Testing the APIs via Postman

We're done developing our backend APIs. Let's run the application and test the APIs via Postman. Type the following command from the root directory of the project to run the application -

                mvn spring-boot:run                              

1. Upload File

2. Upload Multiple Files

3. Download File

Conclusion

That's it. We learned how to upload single as well as multiple files via REST APIs written in Spring Boot. We also learned how to download files in Spring Boot.

I hope the post was helpful to you. You can download the entire code for the project that we built in this article from the GitHub repository.

Learn and master in Spring boot at Spring Boot Tutorial

Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours


Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course

eganboyed1975.blogspot.com

Source: https://www.javaguides.net/2018/11/spring-boot-2-file-upload-and-download-rest-api-tutorial.html

0 Response to "Java Rest Upload File Example"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel