Spring Boot MultipartFile 资源 [file] 无法解析为绝对文件路径

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

提问人:Eldiyar Amanturov 提问时间:9/27/2023 最后编辑:Diego BorbaEldiyar Amanturov 更新时间:9/28/2023 访问量:452

问:

这可能是由于什么原因造成的? 目录在 /opt/docs 中,该文件存在。文件已上传,但我无法将其下载回去

也许我错过了什么,我认为问题出在convertFileFromPath,帮我弄清楚

@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()));
}
Java spring-boot 附件 multipartfile

评论

1赞 M. Deinum 9/27/2023
作为测试依赖项的事实应该表明您不应该使用它。无论如何,您也不应该在响应中使用它。如果要下载它,只需将其写入输出流即可。MockMultipartFile
0赞 Eldiyar Amanturov 9/28/2023
@M.Deinum谢谢你,我成功了

答:

1赞 Euklios 9/27/2023 #1

MockMultipartFile 是一个测试依赖项,不应在非测试代码中使用。此外,MultipartFile 仅用于上传到 API,而不用于下载文件。对于下载,只需返回资源就足够了。

这应该更符合您的需求。

@GetMapping(value = "/download/{id}")
public Resource downloadById(@PathVariable Long id) throws IOException {
    // ...
   Resource resource = new InputStreamResource(new FileInputStream(file));
  return resource;
}
0赞 Eldiyar Amanturov 9/28/2023 #2
@GetMapping(value = "/download/{id}")
public ResponseEntity<InputStreamResource> downloadById(@PathVariable Long id) throws IOException {
    Attachments attachments = repository.findById(id).orElse(null);
    if (attachments == null) {
        return ResponseEntity.notFound().build();
    }
    String fileName = attachments.getName();
    Path filePath = Paths.get(attachments.getPath());
    InputStreamResource resource = new InputStreamResource(new FileInputStream(filePath.toFile()));
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)

            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
            .body(resource);
}