Upload-Download Any FileType .PDF,MP3,MP4,.DOCX in Database and Without Database in SpringBoot :
I have asked to create a file upload-download demo in spring boot on the Gradle build system. So this for my students and beginners who want to understand the API how to develop file upload-download. Even you can view the same in your browser.
Our Spring Boot Application will provide APIs for:
Uploading File to MySQL database
downloading File database with the link
These are APIs to be exported:
Methods Urls Actions
POST /upload upload a File
GET /files get List of Files (name, url, type, size)
GET /files/[fileId] download a File
The uploaded files will be stored in the MySQL Database files table with these fields: id, name, type, and data as BLOB type (Binary Large Object is for storing binary data like file, image, audio, or video).
Let me explain it briefly.
– FileDocument is the data model corresponding to the files table in the database.
– FileDBRepository extends the Spring Data JPA repository which has methods to store and retrieve files.
– FilesStorageService uses FileDBRepository to provide methods for saving new file, get file by id, get list of Files.
– FilesController uses FilesStorageService to export Rest APIs: POST a file, GET all files’ information, download a File.
– FileUploadExceptionAdvice handles exceptions when the controller processes file upload.
– ResponseFile contains information of the file (name, URL, type, size) for HTTP response payload.
– application.YAML contains configuration for Servlet Multipart and MySQL database connection.
– pom.xml for Spring Boot, Spring Data JPA, and MySQL connector dependency.
Full Souce Code Accessible Here on below path:
https://github.com/Abhinaw/demo/tree/master
Below is the test results for reference :
Source Code :
import com.greenlearner.fileuploaddownload.dto.FileUploadResponse;
import com.greenlearner.fileuploaddownload.service.FileStorageService;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@RestController
public class UploadDownloadWithFileSystemController {
private FileStorageService fileStorageService;
public UploadDownloadWithFileSystemController(FileStorageService fileStorageService) {
this.fileStorageService = fileStorageService;
}
@PostMapping("single/upload")
FileUploadResponse singleFileUplaod(@RequestParam("file") MultipartFile file) {
String fileName = fileStorageService.storeFile(file);
///http://localhost:8081/download/abc.jpg
String url = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/download/")
.path(fileName)
.toUriString();
String contentType = file.getContentType();
FileUploadResponse response = new FileUploadResponse(fileName, contentType, url);
return response;
}
@GetMapping("/download/{fileName}")
ResponseEntity<Resource> downLoadSingleFile(@PathVariable String fileName, HttpServletRequest request) {
Resource resource = fileStorageService.downloadFile(fileName);
// MediaType contentType = MediaType.APPLICATION_PDF;
String mimeType;
try {
mimeType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException e) {
mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
mimeType = mimeType == null ? MediaType.APPLICATION_OCTET_STREAM_VALUE : mimeType;
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(mimeType))
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName="+resource.getFilename())
.header(HttpHeaders.CONTENT_DISPOSITION, "inline;fileName=" + resource.getFilename())
.body(resource);
}
@PostMapping("/multiple/upload")
List<FileUploadResponse> multipleUpload(@RequestParam("files") MultipartFile[] files) {
if (files.length > 7) {
throw new RuntimeException("too many files");
}
List<FileUploadResponse> uploadResponseList = new ArrayList<>();
Arrays.asList(files)
.stream()
.forEach(file -> {
String fileName = fileStorageService.storeFile(file);
///http://localhost:8081/download/abc.jpg
String url = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/download/")
.path(fileName)
.toUriString();
String contentType = file.getContentType();
FileUploadResponse response = new FileUploadResponse(fileName, contentType, url);
uploadResponseList.add(response);
});
return uploadResponseList;
}
@GetMapping("zipDownload")
void zipDownload(@RequestParam("fileName") String[] files, HttpServletResponse response) throws IOException {
//zipoutstream - zipentry+zipentry
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
Arrays.asList(files)
.stream()
.forEach(file -> {
Resource resource = fileStorageService.downloadFile(file);
ZipEntry zipEntry = new ZipEntry(resource.getFilename());
try {
zipEntry.setSize(resource.contentLength());
zos.putNextEntry(zipEntry);
StreamUtils.copy(resource.getInputStream(), zos);
zos.closeEntry();
} catch (IOException e) {
System.out.println("some exception while ziping");
}
});
zos.finish();
}
response.setStatus(200);
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=zipfile");
}
}
This is without a database just upload and download files to a particular location.
application.yaml:
server:
port: 8081
file:
storage:
location: fileStorage
spring:
servlet:
multipart:
enabled: true
location: temp123
file-size-threshold: 5MB
max-file-size: 20MB
max-request-size: 20MB
datasource:
url: jdbc:mysql://localhost:3306/db?useSSL=false
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
Gradle dependency:
dependencies {
//my sql connector
compile 'mysql:mysql-connector-java:8.0.17'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
Thanks.
1 comment:
Very good example.
Post a Comment