Мы хотели бы иметь Java REST API для возврата файлов из облачного хранилища Google в виде вложений. Я смог заставить его работать, используя следующий метод. Проблема в том, что файл должен быть загружен локально в контейнер службы (мы развертываем его в Google Cloud Run), и это проблема в случае очень больших файлов и, как правило, может быть плохой практикой. Есть ли способ как-то изменить этот код, чтобы пропустить создание локального файла?
@GetMapping(path = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<InputStreamResource> getSpecificFile(@RequestParam String fileName,
@RequestParam String bucketName, @RequestParam String projectName) {
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Blob blob = storage.get(bucketName, fileName);
ReadChannel readChannel = blob.reader();
String outputFileName = tempFileDestination.concat("\\").concat(fileName);
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFileName)) {
fileOutputStream.getChannel().transferFrom(readChannel, 0, Long.MAX_VALUE);
String contentType = Files.probeContentType(Paths.get(outputFileName));
FileInputStream fileInputStream = new FileInputStream(outputFileName);
return ResponseEntity.ok().contentType(MediaType.valueOf(contentType))
.header("Content-Disposition", "attachment; filename = " + fileName)
.body(new InputStreamResource(fileInputStream));
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.internalServerError().body(null);
} finally {
// delete the local file as cleanup
try {
Files.delete(Paths.get(outputFileName));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Ну, это мне не потребовалось много времени, чтобы понять. Я смог заставить его работать следующим образом:
@GetMapping(path = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<InputStreamResource> getSpecificFile(@RequestParam String fileName, @RequestParam String bucketName, @RequestParam String projectName) {
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Blob blob = storage.get(bucketName, fileName);
ReadChannel readChannel = blob.reader();
try {
String contentType = Files.probeContentType(Paths.get(fileName));
InputStream inputStream = Channels.newInputStream(readChannel);
return ResponseEntity.ok().contentType(MediaType.valueOf(contentType))
.header("Content-Disposition", "attachment; filename = " + fileName)
.body(new InputStreamResource(inputStream));
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.internalServerError().body(null);
}
}
В основном перенаправьте InputStream в readChannel вместо файла.