Files downloaded through a spring controller are corrupted

2k views Asked by At

I have .xlsx, .docx and .pdf files saved on my backend. The download controller looks like this:

@RestController
public class FileDownload {

@RequestMapping(value = "/files/{file_name}/", method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void getFile(
        @PathVariable("file_name") String file,
        HttpServletResponse response) throws Exception {

        String fileType=file.split("\\.")[1];

        switch(fileType){
            case "xlsx": response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                break;
            case "docx": response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
                break;
            case "pdf": response.setContentType("application/pdf");
                break;
            default: response.setContentType("application/octet-stream");
                break;
        }

        response.setHeader("Content-Disposition", "attachment; filename=" + file);
        response.setHeader("Content-Length", String.valueOf(file.length()));

        InputStream is = FileDownload.class.getResourceAsStream("/files/"  + file);

        copy(is, response.getOutputStream());
        response.flushBuffer();
}
}

When trying to open the file, excel tells me it is corrupted and needs to be repaired. The repairing process fails too though.

What could be causing this error?

There are a lot of similar questions but none of the proposed solutions seem to work.

The only "fix" that works is appending a "download" attribute to the link in the frontend which downloads the file. But sadly this doesn't work for IE.

1

There are 1 answers

0
Sean Tai On

I had the same issue for downloading a zip file. My solution was ultimately to instead return a byte array from my controller (see https://stackoverflow.com/a/33302570/4921953) and then handle that on my JavaScript front-end in different ways for Chrome/Firefox (I used the download attribute that you used) and Internet Explorer (see https://stackoverflow.com/a/24354303/4921953). Make sure that you have responseType set to "arraybuffer" when you make the HTTP request from the front end to your server.