Spring boot Rest服务下载包含多个文件的zip文件

问题描述 投票:0回答:4

我可以下载单个文件,但如何下载包含多个文件的 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;
}
rest spring-boot spring-rest
4个回答
13
投票

这是我使用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;
    }
}

4
投票

使用 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
标题。

结合这两个答案即可得到您想要实现的目标。


0
投票
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) {
         
      }
}

0
投票
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());
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.