Spring Boot: file download creates a new file inside the project root folder


Oxides:

I am using a Spring boot 2.2.6.RELEASEbelt Java 11. I have some images in static folder. Example: static/img/category/some_image.jpg.

This method runs in the backend when I click the download button on the GUI.

@ResponseBody
@GetMapping(value = "/download", produces = MediaType.IMAGE_JPEG_VALUE)
public FileSystemResource downloadImage(@Param(value = "url") String url,
                                        @Param(value = "id") Integer id,
                                        HttpServletResponse response) throws IOException {

    Media media = mediaService.findById(id);
    String fileName = media.getFileName();

    InputStream inputStream = new ClassPathResource(url).getInputStream();
    File file = new File(fileName);
    FileUtils.copyToFile(inputStream, file);
    inputStream.close();

    response.addHeader("Content-Disposition", "attachment; filename=" + fileName + ".jpg");
    return new FileSystemResource(file);
}

I am using InputStreambecause I am running this application as a jar file in a docker container. Anyway, this method works fine and the image can be downloaded. But the problem is that after the file is downloaded, a new file without extension ( ) jpgis created in the root directory of the project . Its content looks like this:

ffd8 ffe1 0018 4578 6966 0000 4949 2a00
0800 0000 0000 0000 0000 0000 ffec 0011
4475 636b 7900 0100 0400 0000 3c00 00ff
ee00 0e41 646f 6265 0064 c000 0000 01ff
db00 8400 0604 0404 0504 0605 0506 0906
0506 090b 0806 0608 0b0c 0a0a 0b0a 0a0c
100c 0c0c 0c0c 0c10 0c0e 0f10 0f0e 0c13
...

If I rename the file and add the file jpg extension, the image opens fine. For each downloaded file, a new file will be created inside the project root folder, which is not good. Any idea why this is happening?

Suraj:

This is because File file = new File(fileName);a permanent file is actually created on the classpath.

What needs to be done is to create a temporary file

replace File file = new File(fileName);withFile file = File.createTempFile(fileName, "jpeg");

So the whole method should be like this

@ResponseBody
@GetMapping(value = "/download", produces = MediaType.IMAGE_JPEG_VALUE)
public FileSystemResource downloadImage(@Param(value = "url") String url,
                                        @Param(value = "id") Integer id,
                                        HttpServletResponse response) throws IOException {

    Media media = mediaService.findById(id);
    String fileName = media.getFileName();

    InputStream inputStream = new ClassPathResource(url).getInputStream();
    File file = File.createTempFile(fileName,"");
    FileUtils.copyToFile(inputStream, file);
    inputStream.close();
    file.deleteOnExit(); // delete temp file on exit
    response.addHeader("Content-Disposition", "attachment; filename=" + fileName + ".jpg");
    return new FileSystemResource(file);
}

Related