我可以下载单个文件,但如何下载包含多个文件的 zip 文件。
下面是下载单个文件的代码,但我有多个文件要下载。任何帮助将不胜感激,因为我在过去的两天里一直坚持这个问题。
@GET
@Path("/download/{fname}/{ext}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFile(@PathParam("fname") String fileName,@PathParam("ext") String fileExt){
File file = new File("C:/temp/"+fileName+"."+fileExt);
ResponseBuilder rb = Response.ok(file);
rb.header("Content-Disposition", "attachment; filename=" + file.getName());
Response response = rb.build();
return response;
}
这是我使用response.getOuptStream()的工作代码
@RestController
public class DownloadFileController {
@Autowired
DownloadService service;
@GetMapping("/downloadZip")
public void downloadFile(HttpServletResponse response) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=download.zip");
response.setStatus(HttpServletResponse.SC_OK);
List<String> fileNames = service.getFileName();
System.out.println("############# file size ###########" + fileNames.size());
try (ZipOutputStream zippedOut = new ZipOutputStream(response.getOutputStream())) {
for (String file : fileNames) {
FileSystemResource resource = new FileSystemResource(file);
ZipEntry e = new ZipEntry(resource.getFilename());
// Configure the zip entry, the properties of the file
e.setSize(resource.contentLength());
e.setTime(System.currentTimeMillis());
// etc.
zippedOut.putNextEntry(e);
// And the content of the resource:
StreamUtils.copy(resource.getInputStream(), zippedOut);
zippedOut.closeEntry();
}
zippedOut.finish();
} catch (Exception e) {
// Exception handling goes here
}
}
}
服务等级:-
public class DownloadServiceImpl implements DownloadService {
@Autowired
DownloadServiceDao repo;
@Override
public List<String> getFileName() {
String[] fileName = { "C:\\neon\\FileTest\\File1.xlsx", "C:\\neon\\FileTest\\File2.xlsx", "C:\\neon\\FileTest\\File3.xlsx" };
List<String> fileList = new ArrayList<>(Arrays.asList(fileName));
return fileList;
}
}
使用 Spring MVC 提供的抽象来避免将整个文件加载到内存中。
org.springframework.core.io.Resource
& org.springframework.core.io.InputStreamSource
这样,您的底层实现可以在不更改控制器接口的情况下进行更改,并且您的下载将逐字节流式传输。
请参阅接受的答案here,它基本上使用
org.springframework.core.io.FileSystemResource
来创建Resource
,并且也有一个动态创建zip文件的逻辑。
上面的答案的返回类型为
void
,而您应该直接返回 Resource
或 ResponseEntity<Resource>
。
如这个答案中所示,循环您的实际文件并放入 zip 流中。查看
produces
和 content-type
标题。
结合这两个答案即可得到您想要实现的目标。
public void downloadSupportBundle(HttpServletResponse response){
File file = new File("supportbundle.tar.gz");
Path path = Paths.get(file.getAbsolutePath());
logger.debug("__path {} - absolute Path{}", path.getFileName(),
path.getRoot().toAbsolutePath());
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=supportbundle.tar.gz");
response.setStatus(HttpServletResponse.SC_OK);
System.out.println("############# file name ###########" + file.getName());
try (ZipOutputStream zippedOut = new ZipOutputStream(response.getOutputStream())) {
FileSystemResource resource = new FileSystemResource(file);
ZipEntry e = new ZipEntry(resource.getFilename());
e.setSize(resource.contentLength());
e.setTime(System.currentTimeMillis());
zippedOut.putNextEntry(e);
StreamUtils.copy(resource.getInputStream(), zippedOut);
zippedOut.closeEntry();
zippedOut.finish();
} catch (Exception e) {
}
}
public ResponseEntity<byte[]> downloadFolderAsZip(@RequestParam("id") Long id) throws IOException, InvalidKeyException,
InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException,
InternalException, XmlParserException, ErrorResponseException {
{
// Set the response headers for the ZIP file
List<File> files = folderRepository.findAllByParentFolderById(id);
List<Folder> folders = folderRepository.findAllByParentFolder(id);
Folder folderById = folderRepository.findById(id).get();
// Create ByteArrayOutputStream to hold ZIP file contents
ByteArrayOutputStream zipBytes = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(zipBytes);
// Iterate over each file and add to ZIP
for (com.numeryx.minioaccess.model.File file : files) {
String fileName = file.getName();
String filePath = file.getPath();
// Get file from Minio
InputStream inputStream = ConnectedUserMinioSession.minioClient.getObject(
GetObjectArgs.builder()
.bucket("reports")
.object(file.getPathUuid())
.build());
// Add file to ZIP
zipOut.putNextEntry(new ZipEntry(fileName));
IOUtils.copy(inputStream, zipOut);
zipOut.closeEntry();
inputStream.close();
}
if (!folders.isEmpty()) {
for (Folder folder : folders) {
addFolderToZip(zipOut, folder.getName() ,folder.getId(),"");
}
}
// Close ZIP stream
zipOut.finish();
zipOut.close();
// Set HTTP response headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", "folder.zip");
// Return ZIP file as byte array
return new ResponseEntity<>(zipBytes.toByteArray(), headers, HttpStatus.OK);
}
}
private void addFolderToZip(ZipOutputStream zipOut, String folderName,Long id,String folderSupName) throws IOException,
InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
ServerException, InternalException, XmlParserException, ErrorResponseException {
if (folderSupName != "") {
String[] value = folderSupName.split("/", 4);
// Create a new ZIP entry for the folder
zipOut.putNextEntry(new ZipEntry(value[3] + folderName + "/"));
zipOut.closeEntry();
// Get all files and subfolders in the folder
//List<File> files = fileDBRepository.findAllByParentFolder(folderPathUuid);
List<File> files = folderRepository.findAllByParentFolderById(id);
List<Folder> folders = folderRepository.findAllByParentFolder(id);
Folder folderById = folderRepository.findById(id).get();
// Recursively add all files and subfolders to the ZIP
for (com.numeryx.minioaccess.model.File file : files) {
String fileName = file.getName();
String filePathUuid = file.getPathUuid();
// If the file is not a folder, add it to the ZIP
InputStream inputStream = ConnectedUserMinioSession.minioClient.getObject(
GetObjectArgs.builder()
.bucket("reports")
.object(filePathUuid)
.build());
// Add file to ZIP
zipOut.putNextEntry(new ZipEntry(value[3] + folderName + "/" + fileName));
IOUtils.copy(inputStream, zipOut);
zipOut.closeEntry();
inputStream.close();
}
if (!folders.isEmpty()) {
for (Folder folder : folders) {
addFolderToZip(zipOut, folder.getName(), folder.getId(), folderById.getPath());
}
}
} else {
zipOut.putNextEntry(new ZipEntry(folderSupName + folderName + "/"));
zipOut.closeEntry();
// Get all files and subfolders in the folder
List<File> files = folderRepository.findAllByParentFolderById(id);
List<Folder> folders = folderRepository.findAllByParentFolder(id);
Folder folderById = folderRepository.findById(id).get();
// Recursively add all files and subfolders to the ZIP
for (com.numeryx.minioaccess.model.File file : files) {
String fileName = file.getName();
String filePathUuid = file.getPathUuid();
// If the file is not a folder, add it to the ZIP
InputStream inputStream = ConnectedUserMinioSession.minioClient.getObject(
GetObjectArgs.builder()
.bucket("reports")
.object(filePathUuid)
.build());
// Add file to ZIP
zipOut.putNextEntry(new ZipEntry(folderSupName + folderName + "/" + fileName));
IOUtils.copy(inputStream, zipOut);
zipOut.closeEntry();
inputStream.close();
}
if (!folders.isEmpty()) {
for (Folder folder : folders) {
addFolderToZip(zipOut, folder.getName(), folder.getId(), folderById.getPath());
}
}
}
}