Detailed Explanation of Spring MVC File Download Example

  • 2021-12-19 06:29:07
  • OfStack

Detailed Explanation of Spring MVC File Download Example

Read a file

To download the file, the first is to read the contents of the file in, using byte array storage, here using spring inside the tool class implementation


import org.springframework.util.FileCopyUtils;

  public byte[] downloadFile(String fileName) {
    byte[] res = new byte[0];
    try {
      File file = new File(BACKUP_FILE_PATH, fileName);
      if (file.exists() && !file.isDirectory()) {
        res = FileCopyUtils.copyToByteArray(file);
      }
    } catch (IOException e) {
      logger.error(e.getMessage());
    }
    return res;
  }

This array is the contents of the file, which will be output to the response for the browser to download

Download the response of the file

The response header of downloading files is different from the response header like 1, and it should be treated differently according to the different browsers of users

I encapsulated the code that generated the response into a method, so that all downloaded responses can call this method, avoiding duplicate code writing everywhere


 protected ResponseEntity<byte[]> downloadResponse(byte[] body, String fileName) {
    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
        .getRequestAttributes()).getRequest();
    String header = request.getHeader("User-Agent").toUpperCase();
    HttpStatus status = HttpStatus.CREATED;
    try {
      if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        fileName = fileName.replace("+", "%20");  // IE Download file name space change + Number problem 
        status = HttpStatus.OK;
      } else {
        fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
      }
    } catch (UnsupportedEncodingException e) {}

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDispositionFormData("attachment", fileName);
    headers.setContentLength(body.length);

    return new ResponseEntity<byte[]>(body, headers, status);
  }

Note here, 1 generally downloaded files are using 201 status code, but the IE browser does not support, but I have to spend a lot of effort to find out that is the problem

Among them, the processing of file name is to prevent Chinese and space from causing file name garbled

Controller method

Where in the controller, the return value needs to be processed


@RequestMapping(value = "/download-backup", method = RequestMethod.GET)
  @ResponseBody
  public ResponseEntity<byte[]> downloadBackupFile(@RequestParam String fileName) {
    byte[] body = backupService.downloadFile(fileName);
    return downloadResponse(body, fileName);
  }
 

Thank you for reading, hope to help everyone, thank you for your support to this site!


Related articles: