Showing posts with label File Upload and Download Spring Boot Java. Show all posts
Showing posts with label File Upload and Download Spring Boot Java. Show all posts

Saturday, May 15, 2021

Upload-Download Any FileType .PDF,MP3,MP4,.DOCX in Database and Without Database in SpringBoot Gradle Build System - Java

 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 :



Folder Location where file is getting stored : FileStorage Folder in project

     Folder Location where file is getting stored

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.