Search code examples
javaspring-bootattachmentmultipartfile

Spring Boot MultipartFile resource [file] cannot be resolved to absolute file path


What could this be due to? the directory is in /opt/docs, the file exists. The file is uploaded, but I can’t download it back

Maybe I missed something, I think the problem is convertFileFromPath, help me figure it out

@PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE})
public AttachmentResponseDto uploadFile(@RequestPart AttachmentRequestDto dto, @RequestPart MultipartFile file) throws IOException {
    return service.saveAttachment(file, dto.getType());
}

@GetMapping(value = "/download/{id}")
public AttachmentResponseDto downloadById(@PathVariable Long id) throws IOException {
    return service.getFileById(id);
}

@Value("${file.storage.docs}")
private String docDirectory;

@Override
public AttachmentResponseDto saveAttachment(MultipartFile file, String type) throws IOException {
    AttachmentResponseDto responseDto = new AttachmentResponseDto();
    String extension = StringUtils.getFilenameExtension(file.getOriginalFilename());
    String fileName = Objects.requireNonNull(type).concat("№" + UUID.randomUUID().toString()).concat("." + extension);
    Path root = Paths.get(docDirectory);
    Files.copy(file.getInputStream(), root.resolve(fileName));
    responseDto.setFilePath(root.toString().concat("/").concat(fileName));
    responseDto.setType(type);
    responseDto.setExtension(extension);
    responseDto.setName(fileName);
    Attachments attachments = convertDtoToEntity(responseDto);
    Attachments saved = repository.save(attachments);
    responseDto.setAttachmentId(saved.getId());
    return responseDto;
}

@Override
public AttachmentResponseDto getFileById(Long id) throws IOException {
    Attachments getById = repository.findById(id).get();
    AttachmentResponseDto responseDto = convertDtoToEntity(getById);
    responseDto.setFile(convertFileFromPath(getById));
    return responseDto;
}

@Override
public MultipartFile convertFileFromPath(Attachments attachments) throws IOException {
    return new MockMultipartFile(attachments.getName(), new FileInputStream(attachments.getPath()));
}

Solution

  • MockMultipartFile is a test dependency and should never be used in your non-testing code. Additionally, MultipartFile is only used to upload to your API, not to download the file. For downloading, simply returning the resource is sufficient.

    This should be more in line with what you need.

    @GetMapping(value = "/download/{id}")
    public Resource downloadById(@PathVariable Long id) throws IOException {
        // ...
       Resource resource = new InputStreamResource(new FileInputStream(file));
      return resource;
    }