In this tutorial, I will show you File download using Spring WebFlux example.
This Spring Boot App works with:
– Angular 8 / Angular 10 / Angular 11 / Angular 12 / Angular 13 / Angular 14 / Angular 15
– Angular Material 12
– Vue Client / Vuetify Client
– React Client / React Hooks Client
– React Image Upload with Preview
– Material UI Client
– Axios Client
Related Posts:
– Spring Boot Delete File example
– Spring Boot WebFlux Rest API example
– Spring Boot Thymeleaf File Upload example
– How to upload multiple files in Java Spring Boot
– Spring Boot Upload/Download File to/from Database example
– Spring Boot: Upload/Import Excel file data into MySQL Database
– Spring Boot: Upload/Import CSV file data into MySQL Database
– Documentation: Spring Boot Swagger 3 example
– Caching: Spring Boot Redis Cache example
Deployment: Deploy Spring Boot App on AWS – Elastic Beanstalk
Contents
Spring WebFlux File download example Overview
Our Spring Boot Reactive Web – WebFlux File Upload Application will provide API for downloading File from server with the url link.
Here is the API to be exported:
Methods | Urls | Actions |
---|---|---|
GET | /files/[filename] | download a File |
This is the static folder that stores all uploaded files:
For deleting file, kindly visit:
Spring Boot Delete File example
Technology
- Java 17/11
- Spring Boot 3/2 (with Spring WebFlux)
- Maven 3.6.1
Setup Spring Boot project
Open pom.xml and add WebFlux dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Create Service for File Download
service/FileStorageService.java
package com.bezkoder.spring.webflux.file.service;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
@Service
public class FileStorageService {
private final Path root = Paths.get("uploads");
@Override
public Flux<DataBuffer> load(String filename) {
try {
Path file = root.resolve(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return DataBufferUtils.read(resource, new DefaultDataBufferFactory(), 4096);
} else {
throw new RuntimeException("Could not read the file!");
}
} catch (MalformedURLException e) {
throw new RuntimeException("Error: " + e.getMessage());
}
}
}
Firstly, we read the file content as a Resource
.
Then if the resource exists, we create a Flux
of DataBuffer
from the file content using DataBufferUtils
class, and set a buffer size of 4096
bytes. You can adjust the buffer size depending on your use case.
Create Controller for WebFlux File download
In controller package, we create FileController
.
controller/FileController.java
package com.bezkoder.spring.webflux.file.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.bezkoder.spring.webflux.file.service.FileStorageService;
import reactor.core.publisher.Flux;
@Controller
@CrossOrigin("http://localhost:8081")
public class FileController {
@Autowired
FileStorageService storageService;
@GetMapping("/files/{filename:.+}")
public ResponseEntity<Flux<DataBuffer>> getFile(@PathVariable String filename) {
Flux<DataBuffer> file = storageService.load(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM).body(file);
}
}
– @CrossOrigin
is for configuring allowed origins.
– @Controller
annotation is used to define a controller.
– @GetMapping
annotation is for mapping HTTP GET /files/[filename]
requests onto getFile()
method.
– We use @Autowired
to inject implementation of FileStorageService
bean to local variable.
– Then use FileStorageService
‘s load()
method to create a Flux
of DataBuffer
from the file, and use the body()
method of ResponseEntity
to write the file content to the response.
– We also use body()
and contentType()
method to set the file name and content type in the response headers.
Source Code
You can find the complete source code for this tutorial on Github.
With Template Engine:
Spring Boot Thymeleaf File Upload/Download example
Conclusion
Today we’ve learned how to create Spring Boot example – Spring WebFlux File Download from a static folder.
Following tutorials explain how to build Front-end Apps to work with our Spring Boot Server:
– Angular 8 / Angular 10 / Angular 11 / Angular 12 / Angular 13 / Angular 14 / Angular 15
– Angular Material 12
– Vue Client / Vuetify Client
– React Client / React Hooks Client
– React Image Upload with Preview
– Material UI Client
– Axios Client
For deleting file:
Spring Boot Delete File example
You can also know way to download an Excel/CSV file from database with the post:
– Spring Boot Download Excel file from Database example
– Spring Boot Download CSV file from Database example
If you want to store files in database like this:
You can find instruction at:
Spring Boot Upload/Download File to/from Database example
Happy Learning! See you again.
Further Reading
- Multipart Content-Type
- Spring FilePart
- Spring Boot WebFlux Rest API example
- Spring Boot upload Image and Display with Thymeleaf
- Documentation: Spring Boot + Swagger 3 example (with OpenAPI 3)
- Caching: Spring Boot Redis Cache example