在本文中,您将学习如何在 Restful Spring Boot Web 服务中上传和下载文件。 文件将存储在 MySQL 数据库中。
这篇文章是之前一篇文章的延续,我已经展示了如何上传文件并将它们存储在本地文件系统中。
我们将重用上一篇文章中描述的大部分代码和概念。所以我强烈建议你在阅读这篇文章之前先读一遍。
完整代码可在 Github 存储库中找到。
以下是完整应用的目录结构,供大家参考——
由于我们将在 MySQL 数据库中存储文件,因此我们需要 JPA 和 MySQL 依赖项以及 Web 依赖项。因此,请确保您的 pom
文件包含以下依赖项 -
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
如果您是从头开始构建项目,则可以从 Spring Initialzr 网站生成项目框架。
接下来,我们需要配置 MySQL 数据库 url、用户名和密码。您可以在 src/main/resources/application.properties
文件中进行配置 -
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url= jdbc:mysql://localhost:3306/file_demo?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username= root
spring.datasource.password= callicoder
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
## Hibernate Logging
logging.level.org.hibernate.SQL= DEBUG
## 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
上面的属性文件也有 Multipart 文件属性。您可以根据自己的要求更改这些属性。
让我们创建一个 DBFile
实体来建模将存储在数据库中的 file
属性 -
package com.example.filedemo.model;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Entity
@Table(name = "files")
public class DBFile {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
private String fileName;
private String fileType;
@Lob
private byte[] data;
public DBFile() {
}
public DBFile(String fileName, String fileType, byte[] data) {
this.fileName = fileName;
this.fileType = fileType;
this.data = data;
}
// Getters and Setters (Omitted for brevity)
}
请注意,文件的内容将作为字节数组存储在数据库中。
接下来,我们需要创建一个存储库来保存数据库中的文件并检索它们 -
package com.example.filedemo.repository;
import com.example.filedemo.model.DBFile;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface DBFileRepository extends JpaRepository<DBFile, String> {
}
以下 DBFileStorageService
包含在数据库中存储和检索文件的方法 -
package com.example.filedemo.service;
import com.example.filedemo.exception.FileStorageException;
import com.example.filedemo.exception.MyFileNotFoundException;
import com.example.filedemo.model.DBFile;
import com.example.filedemo.repository.DBFileRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@Service
public class DBFileStorageService {
@Autowired
private DBFileRepository dbFileRepository;
public DBFile 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);
}
DBFile dbFile = new DBFile(fileName, file.getContentType(), file.getBytes());
return dbFileRepository.save(dbFile);
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
public DBFile getFile(String fileId) {
return dbFileRepository.findById(fileId)
.orElseThrow(() -> new MyFileNotFoundException("File not found with id " + fileId));
}
}
最后,以下是上传和下载文件的 Rest API -
package com.example.filedemo.controller;
import com.example.filedemo.model.DBFile;
import com.example.filedemo.payload.UploadFileResponse;
import com.example.filedemo.service.DBFileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@RestController
public class FileController {
private static final Logger logger = LoggerFactory.getLogger(FileController.class);
@Autowired
private DBFileStorageService dbFileStorageService;
@PostMapping("/uploadFile")
public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file) {
DBFile dbFile = dbFileStorageService.storeFile(file);
String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(dbFile.getId())
.toUriString();
return new UploadFileResponse(dbFile.getFileName(), fileDownloadUri,
file.getContentType(), file.getSize());
}
@PostMapping("/uploadMultipleFiles")
public List<UploadFileResponse> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {
return Arrays.asList(files)
.stream()
.map(file -> uploadFile(file))
.collect(Collectors.toList());
}
@GetMapping("/downloadFile/{fileId}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileId) {
// Load file from database
DBFile dbFile = dbFileStorageService.getFile(fileId);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(dbFile.getFileType()))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + dbFile.getFileName() + "\"")
.body(new ByteArrayResource(dbFile.getData()));
}
}
我将重用我在本文第一部分演示的完整前端代码。您应该查看第一篇文章以了解有关前端代码的更多信息,或从 Github 下载。
准备好前端代码后,键入以下命令以运行应用程序 -
mvn spring-boot:run
这是最终应用程序的屏幕截图 -
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.callicoder.com/spring-boot-file-upload-download-jpa-hibernate-mysql-database-example/
内容来源于网络,如有侵权,请联系作者删除!