0

I'm trying to implement this Spring endpoint:

private static String UPLOADED_FOLDER = "/opt/";

@PostMapping(value = "/upload", produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<StringResponseDTO> uploadFile(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes, @RequestParam("id") Integer merchant_id) throws Exception {

        InputStream inputStream = file.getInputStream();

        try {
            byte[] bytes = file.getBytes();

            File directory = new File(UPLOADED_FOLDER, merchant_id.toString());
            directory.mkdirs();
            File newFile = new File(directory, file.getOriginalFilename());
            newFile.renameTo(new File("merchant_logo.png"));
            Files.write(newFile.toPath(), bytes);

            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded '" + file.getOriginalFilename() + "'");

        } catch (IOException e) {
            e.printStackTrace();
        }

        return ResponseEntity.ok(new StringResponseDTO(originalName));
    }

The general idea is to rename the file and override previous file with the same name. But for some reason it's not working. I get the old file content. Any idea why?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • 1
    `renameTo` probably won't work if the target file already exists, try deleting it first. – Arnaud Aug 23 '19 at 07:38
  • When you are renaming the file, try to keep the correct file path with the new name in the `renameTo` method – mnestorov Aug 23 '19 at 07:44
  • Probably yes, is there some other way to rename a file? – Peter Penzov Aug 23 '19 at 07:44
  • @mnestorov can you show me code example please? – Peter Penzov Aug 23 '19 at 07:45
  • @PeterPenzov I guess you've seen [this](https://stackoverflow.com/questions/1158777/rename-a-file-using-java). Here the answer says that we must be careful when renaming and we must pass a proper path in that method – mnestorov Aug 23 '19 at 07:46
  • 1
    This code is weird. You could just create a new file with new content, and delete the old file. Or I am missing something ? – Benoit Aug 23 '19 at 07:50
  • 1
    can you try the below code instead of rename Path source = Paths.get("/Users/suman.das/Downloads/data1.csv"); Files.move(source, source.resolveSibling("data1.csv"), REPLACE_EXISTING); – dassum Aug 23 '19 at 07:57
  • 1
    Besides your code beeing rather strange (renames file.getOriginalFilename() an existing file and then overwrites it, newFile and "merchant_logo.png" are in different directories which "rename" won't handle) your code is highly insecure! Never use (insecure) input directly as filesnames without properly validating them. An external attacker could acces any file that the application is able to acces via your method! – TomB Aug 23 '19 at 09:01

2 Answers2

1

Am using java 1.8, maybe this will help you out.

    @PostMapping(value = "/upload", produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file,
            RedirectAttributes redirectAttributes, @RequestParam("id") Integer merchantId) throws Exception {
        try {
            File directory = new File(properties.getFileUploadDir(), merchantId.toString());
            directory.mkdirs();
            Path writeTargetPath = Files.write(
                    Paths.get(directory.getAbsolutePath(), file.getOriginalFilename()).toAbsolutePath(),
                    file.getBytes(), StandardOpenOption.CREATE_NEW);
            Path fileToMovePath = Paths.get(properties.getFileUploadDir(), merchantId.toString(), "merchant_logo.png");
            Path movedPath = Files.move(writeTargetPath, fileToMovePath, StandardCopyOption.REPLACE_EXISTING);
            log.info("movedPath: {}", movedPath.toAbsolutePath());

            redirectAttributes.addFlashAttribute("message",
                    "Successfully uploaded '" + file.getOriginalFilename() + "'");
        } catch (IOException e) {
            log.error("IOException: {}", e);
            return ResponseEntity.ok("Upload failed'" + file.getOriginalFilename() + "'");
        }
        return ResponseEntity.ok("Successfully uploaded'" + file.getOriginalFilename() + "'");
    }
  • I can't resolve `properties`. What I need to import? – Peter Penzov Aug 29 '19 at 13:33
  • I get error java.nio.file.FileAlreadyExistsException: /opt/1/download.png How the old file can be overwritten? – Peter Penzov Aug 29 '19 at 13:57
  • 1. instead of hard coding UPLOADED_FOLDER value, am getting that value from properties file. 2. I have tried with windows, don't have such type of issue, your'e trying with Linux, can you please verify your folder permissions. – Seshu Kandimalla Aug 30 '19 at 09:34
0

Try changing new File("merchant_logo.png") as new File(directory,"merchant_logo.png") to write file in right directory.

Also removing the old file before writing new one can help not to have such issues.

mnestorov
  • 4,116
  • 2
  • 14
  • 24
Codezilla
  • 11
  • 2