Downloading a file from spring controllers

前端 未结 14 1078
渐次进展
渐次进展 2020-11-22 01:06

I have a requirement where I need to download a PDF from the website. The PDF needs to be generated within the code, which I thought would be a combination of freemarker and

14条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-22 01:31

    If you:

    • Don't want to load the whole file into a byte[] before sending to the response;
    • Want/need to send/download it via InputStream;
    • Want to have full control of the Mime Type and file name sent;
    • Have other @ControllerAdvice picking up exceptions for you (or not).

    The code below is what you need:

    @RequestMapping(value = "/stuff/{stuffId}", method = RequestMethod.GET)
    public ResponseEntity downloadStuff(@PathVariable int stuffId)
                                                                          throws IOException {
        String fullPath = stuffService.figureOutFileNameFor(stuffId);
        File file = new File(fullPath);
        long fileLength = file.length(); // this is ok, but see note below
    
        HttpHeaders respHeaders = new HttpHeaders();
        respHeaders.setContentType("application/pdf");
        respHeaders.setContentLength(fileLength);
        respHeaders.setContentDispositionFormData("attachment", "fileNameIwant.pdf");
    
        return new ResponseEntity(
            new FileSystemResource(file), respHeaders, HttpStatus.OK
        );
    }
    

    About the file length part: File#length() should be good enough in the general case, but I thought I'd make this observation because it does can be slow, in which case you should have it stored previously (e.g. in the DB). Cases it can be slow include: if the file is large, specially if the file is in a remote system or something more elaborated like that - a database, maybe.



    InputStreamResource

    If your resource is not a file, e.g. you pick the data up from the DB, you should use InputStreamResource. Example:

        InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
        return new ResponseEntity(isr, respHeaders, HttpStatus.OK);
    

提交回复
热议问题