如何在 Java/Spring 中将文件下载为 blob/byte
How to download a file as a blob/byte in Java/Spring
我有一个 Spring 引导应用程序,它允许用户上传文件(例如 .doc 或 jpeg)并将它们保存到 H2 数据库中。虽然我能够从数据库中保存和检索文件,并将数据保存为字节,但我无法让用户将文件下载到他们的机器上。
我在网上找到的现有解决方案,比如这个one
要么不考虑将 Blob 保存为字节,要么涉及复杂的 sql 查询,这些查询似乎不适合我的应用程序或控制器操作的上下文。
如何在从 H2 数据库中检索 blob 后将其下载到用户的机器上?
我当前的控制器操作是从 href 触发的:
@GetMapping("/download")
public String downloadFile() {
List<Files> files = fileMapper.getFiles();
Files newFile = files.get(0);
byte[] downloadedFile = newFile.getFileData();
return "home";
}
我这里也有我的仓库:
您可以从 org.springframework.core.io.Resource
导入 Resource
并从您的文件创建 InputStreamResource
,应该如下所示:
public ResponseEntity<Resource> downloadFile() {
byte[] bytes = yourMethodToGetByteBlobFromDB(....);
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(bytes));
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Disposition", String.format("attachment; filename=your_file_name"));
return ResponseEntity.ok()
.headers(headers)
.contentLength(bytes.length)
.contentType("application/octet-stream")
.body(resource);
}
下面的代码非常适合我。
在服务中下载逻辑class
public ResponseEntity<Resource> downloadFile(String fileId) throws Exception
{
try
{
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()));
}
catch(Exception e)
{
throw new Exception("Error downloading file");
}
}
DB 文件存储服务
public DBFile getFile(String fileId) throws Exception {
return dbFileRepository.findById(fileId)
.orElseThrow(() -> new Exception("File not found with id " + fileId));
}
数据库文件回购
@Repository
public interface DBFileRepository extends JpaRepository<DBFile, String> {
}
数据库文件的实体Class
@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;
//getter and setter
}
我有一个 Spring 引导应用程序,它允许用户上传文件(例如 .doc 或 jpeg)并将它们保存到 H2 数据库中。虽然我能够从数据库中保存和检索文件,并将数据保存为字节,但我无法让用户将文件下载到他们的机器上。
我在网上找到的现有解决方案,比如这个one
要么不考虑将 Blob 保存为字节,要么涉及复杂的 sql 查询,这些查询似乎不适合我的应用程序或控制器操作的上下文。
如何在从 H2 数据库中检索 blob 后将其下载到用户的机器上?
我当前的控制器操作是从 href 触发的:
@GetMapping("/download")
public String downloadFile() {
List<Files> files = fileMapper.getFiles();
Files newFile = files.get(0);
byte[] downloadedFile = newFile.getFileData();
return "home";
}
我这里也有我的仓库:
您可以从 org.springframework.core.io.Resource
导入 Resource
并从您的文件创建 InputStreamResource
,应该如下所示:
public ResponseEntity<Resource> downloadFile() {
byte[] bytes = yourMethodToGetByteBlobFromDB(....);
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(bytes));
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Disposition", String.format("attachment; filename=your_file_name"));
return ResponseEntity.ok()
.headers(headers)
.contentLength(bytes.length)
.contentType("application/octet-stream")
.body(resource);
}
下面的代码非常适合我。
在服务中下载逻辑class
public ResponseEntity<Resource> downloadFile(String fileId) throws Exception
{
try
{
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()));
}
catch(Exception e)
{
throw new Exception("Error downloading file");
}
}
DB 文件存储服务
public DBFile getFile(String fileId) throws Exception {
return dbFileRepository.findById(fileId)
.orElseThrow(() -> new Exception("File not found with id " + fileId));
}
数据库文件回购
@Repository
public interface DBFileRepository extends JpaRepository<DBFile, String> {
}
数据库文件的实体Class
@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;
//getter and setter
}