Spring MVC 如何通过spring @RestController提供压缩文件下载?

oyt4ldly  于 2023-03-03  发布在  Spring
关注(0)|答案(3)|浏览(201)

我有一个servlet,它提供了一个CSV文件供下载:

@RestController 
@RequestMapping("/")
public class FileController {

    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public FileSystemResource getFile() {
        return new FileSystemResource("c:\file.csv"); 
    }
}

这个很好用。
问:我如何提供这个文件作为压缩文件?(zip,gzip,tar不重要)?

5vf7fwbs

5vf7fwbs1#

基于解决方案here(对于普通的Servlet),您还可以使用基于Spring MVC的控制器执行相同的操作。

@RequestMapping(value = "/export", method = RequestMethod.GET)
public void getFile(OutputStream out) {
    FileSystemResource resource = new FileSystemResource("c:\file.csv"); 
    try (ZipOutputStream zippedOut = new ZipOutputStream(out)) {
        ZipEntry e = new ZipEntry(resource.getName());
        // 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) {
        // Do something with Exception
    }        
}

我们基于响应OutputStream创建了一个ZipOutputStream(可以简单地将其注入到方法中),然后为压缩出来的流创建一个条目并写入它。
除了OutputStream,您还可以连接HttpServletResponse,以便能够设置文件名和内容类型。

@RequestMapping(value = "/export", method = RequestMethod.GET)
public void getFile(HttpServletResponse response) {
    FileSystemResource resource = new FileSystemResource("c:\file.csv"); 
    response.setContentType("application/zip");
    response.setHeader("Content-Disposition", "attachment; filename=file.zip");

    try (ZipOutputStream zippedOut = new ZipOutputStream(response.getOutputStream())) {
        ZipEntry e = new ZipEntry(resource.getName());
        // 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) {
        // Do something with Exception
    }        
}
wsewodh2

wsewodh22#

未经测试,但类似的东西应该工作:

final Path zipTmpPath = Paths.get("C:/file.csv.zip");
final ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipTmpPath, StandardOpenOption.WRITE));
final ZipEntry zipEntry = new ZipEntry("file.csv");
zipOut.putNextEntry(zipEntry);
Path csvPath = Paths.get("C:/file.csv");
List<String> lines = Files.readAllLines(csvPath);
for(String line : lines)
{
    for(char c : line.toCharArray())
    {
        zipOut.write(c);
    }
}
zipOut.flush();
zipOut.close();
return new FileSystemResource("C:/file.csv.zip");
6qfn3psc

6qfn3psc3#

使用此:
@请求Map(值= "/zip ",生成="应用程序/zip ")
这可能会解决您的问题

相关问题