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

mem*_*und 2 java spring spring-mvc

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

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

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

这很好用.

问题:如何将此文件作为压缩文件提供?(zip,gzip,tar没关系)?

M. *_*num 7

基于此处的解决方案(对于普通的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
    }        
}
Run Code Online (Sandbox Code Playgroud)

ZipOutputStream基于响应创建了一个OutputStream(您可以简单地将其注入到方法中).然后为压缩流创建一个条目并写入.

而不是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
    }        
}
Run Code Online (Sandbox Code Playgroud)