Spring Boot file upload/download example

Hello everyone, today we will learn how to upload files/download files in the Spring Boot web application. You can download the source code from our GitHub repository.
Technologies used:
  • Spring Boot 2.5.5
  • Spring MVC 5.3.10 
  • Maven 3
  • JDK 11
  • jQuery
  • Bootstrap
  • Thymeleaf 2.5.5
  • Ajax

User Interface



Project Structure:

 


Pom.xml:

POM stands for project object model. It's the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used to build the project. It downloads required libraries easily using POM XML tags.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<!-- lookup parent from repository -->
</parent>
<groupId>com.knowledgefactory</groupId>
<artifactId>springboot-fileupload-filedownload</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-fileupload-filedownload</name>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- spring mvc, rest -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<description>springboot-fileupload-filedownload</description>
</project> 


UploadDownloadService.java
package com.knowledgefactory.knowledgefactorydemo.service;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
public class UploadDownloadService {
private static final String path = "/home/user/Desktop/files";

public List<String> uploadFile(MultipartFile file)
                  throws Exception {

// Save file on system
if (!file.getOriginalFilename().isEmpty()) {
BufferedOutputStream outputStream = new BufferedOutputStream(
new FileOutputStream(new File(path, file.getOriginalFilename())));
outputStream.write(file.getBytes());
outputStream.flush();
outputStream.close();
} else {
throw new Exception();
}

List<String> list = new ArrayList<String>();
File files = new File(path);
String[] fileList = ((File) files).list();
for (String name : fileList) {
list.add(name);
}
return list;
}

public List<String> getListofFiles() throws Exception {

List<String> list = new ArrayList<String>();
File files = new File(path);
String[] fileList = ((File) files).list();
for (String name : fileList) {
list.add(name);
}
return list;
}
}


Home Controller
package com.knowledgefactory.knowledgefactorydemo.controller;

import com.knowledgefactory.knowledgefactorydemo.
                              service.UploadDownloadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@RestController
public class HomeController {

private static final String path = "/home/user/Desktop/files/";
@Autowired
UploadDownloadService service;

@PostMapping("/uploadFile")
public ResponseEntity<List<String>>
fileUpload(@RequestParam("file") MultipartFile file)
throws Exception {
return new ResponseEntity<>(service.uploadFile(file),
HttpStatus.OK);

}

@RequestMapping(path = "/download", method = RequestMethod.GET)
public ResponseEntity<Resource>
download(@RequestParam String param) throws IOException {
File file = new File(path + param);
Path path = Paths.get(file.getAbsolutePath());
ByteArrayResource resource =
new ByteArrayResource(Files.readAllBytes(path));
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename="+param);
header.add("Cache-Control",
"no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
return ResponseEntity.ok().headers(header).
contentLength(file.length())
.contentType(MediaType.
parseMediaType("application/octet-stream")).
body(resource);
}

@GetMapping("/getListOfFiles")
public ResponseEntity<List<String>> getListOfFiles()
throws Exception {
return new ResponseEntity<>(service.getListofFiles(),
HttpStatus.OK);

}
}
The @RestController annotation was introduced in Spring 4.0 to simplify the engendering of RESTful web services. It's a convenience annotation that combines @Controller and @ResponseBody


Web Controller
package com.knowledgefactory.knowledgefactorydemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class WebController {

@GetMapping("/")
public String index() {
return "index";
}
}



Spring Boot Main Driver

The Spring Boot application's main class contains a public static void main() method that starts up the Spring ApplicationContext.
package com.knowledgefactory.knowledgefactorydemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class KnowledgefactorydemoApplication {

public static void main(String[] args) {
SpringApplication.
                   run(KnowledgefactorydemoApplication.class, args);
}
}


application.properties
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


index.html
<!DOCTYPE html>
<html>
<head>
<title>Knf|File upload and download</title>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
rel="stylesheet">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">
</script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js">
</script>
</head>
<body>
<!-- Site container -->
<div class="container">
<section class="content">
<div class="container">
<h2>Spring Boot-File upload and download</h2>
<hr>
<!-- File Upload From -->
<form action="fileUpload" enctype="multipart/form-data"
method="post">
<div class="form-group">
<label>Select File</label> <input class="form-control"
name="file" type="file">
</div>
<div class="form-group">
<button class="btn btn-primary" id="uploadfile" type="submit">Upload</button>
</div>
</form>
<br/>
<!-- Bootstrap Progress bar -->
<div class="progress">
<div aria-valuemax="100" aria-valuemin="0"
aria-valuenow="0" class="progress-bar progress-bar-success" id="progressBar"
role="progressbar" style="width: 0%">0%
</div>
</div>

<!-- Alert -->
<div id="alertMsg" style="color: red; font-size: 18px;"></div>
</div>
<div id="list"></div>
</br>
<div id="result">
<div class="row align-items-center justify-content-center" id="download">
</div>
</div>
</section>
</div>
<script src="../../dist/js/controller.js"></script>
</body>
</html>


controller.js
$(function () {
load()
$('button[type=submit]')
.click(
function (e) {
e.preventDefault();
// Disable submit button
$(this).prop('disabled', true);
var form = document.forms[0];
var formData = new FormData(form);
// Ajax call for file uploaling
var ajaxReq = $
.ajax({
url: 'uploadFile',
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
xhr: function () {
// Get XmlHttpRequest object
var xhr = $.ajaxSettings.xhr();
// Set onprogress event handler
xhr.upload.onprogress = function (event) {
var perc = Math
.round((event.loaded / event.total) * 100);
$('#progressBar').text(perc + '%');
$('#progressBar').css('width',
perc + '%');
};
return xhr;
},
beforeSend: function (xhr) {
// Reset alert message and progress bar
$('#alertMsg').text('');
$('#progressBar').text('');
$('#progressBar').css('width', '0%');
}
});
// Called on success of file upload
ajaxReq
.done(function (msg) {
$('#alertMsg').text(
"File Uploaded successfully");
$('input[type=file]').val('');
$('button[type=submit]').prop('disabled',
false);
var trHTML = '';
trHTML += '<h3>Download file</h3><ul
class="list-group">'
for (var i = 0; i < msg.length; i++) {
var item = msg[i];
trHTML += '<li class="list-group-item">
<a href="download?param='
+ item
+ '">'
+ item
+ '</a></li>'
}
trHTML += '</ul>'
$('#download').html(trHTML);
});
// Called on failure of file upload
ajaxReq.fail(function (jqXHR) {
$('#alertMsg').text(
jqXHR.responseText + '(' + jqXHR.status
+ ' - ' + jqXHR.statusText + ')');
$('button[type=submit]').prop('disabled', false);
});
});
function load() {
$
.ajax({
type: "GET",
url: "getListOfFiles",
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
},
success: function (msg) {
var trHTML = '';
trHTML += '<h3>Download file</h3><ul class="list-group">'
for (var i = 0; i < msg.length; i++) {
var item = msg[i];
trHTML += '<li class="list-group-item">
<a href="download?param='
+ item + '">' + item + '</a></li>'
}
trHTML += '</ul>'
$('#download').html(trHTML);
}
});
}
});


Local Setup:

Step 1: Download or clone the source code to a local machine.

Step 2mvn clean install

Step 3: Run the Spring Boot application
mvn spring-boot:run

 

More related topics,

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete