我們有 S3 存盤,有很多檔案,jpg、mp3 和其他我需要做什么?我需要重定向客戶端以從我們的 s3 獲取檔案而不將其上傳到我們的服務器上,我希望該客戶在他的電腦上獲取帶有名稱和擴展名的檔案
所以看起來客戶端向我們發送了 uuid - 我們在 s3 上找到這個檔案的鏈接并像這樣重定向它
@GetMapping("/test/{uuid}")
public ResponseEntity<Void> getFile(@PathVariable UUID uuid) {
var url = storageServiceS3.getUrl(uuid);
try {
var name = storageServiceS3.getName(uuid);
return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY)
.header(HttpHeaders.LOCATION, url)
.header(HttpHeaders.CONTENT_TYPE, new MimetypesFileTypeMap().getContentType(name))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" name)
.build();
} catch (NoSuchKeyException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.build();
}
}
一切正常,檔案正在下載,但有一個問題 - 檔案沒有名稱(它的名稱仍然是 s3 的關鍵)并且沒有擴展名。
我認為這段代碼不能正常作業
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" name)
有什么辦法可以做到這一點,或者我仍然需要將檔案上傳到服務器,然后將其發送到客戶端?
uj5u.com熱心網友回復:
最后我找到了解決方案 - 我使用 S3Presigner ,制作預先簽名的 url 并使用簡單的 Http 回應重定向它
@Bean
public S3Presigner getS3Presigner() {
return S3Presigner.builder()
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(ACCESS_KEY, SECRET_KEY)))
.region(Region.of(REGION))
.endpointOverride(URI.create(END_POINT))
.build();
}
public String getPresignedURL(UUID uuid) {
var name = getName(uuid);
var contentDisposition = "attachment;filename=" name;
var contentType = new MimetypesFileTypeMap().getContentType(name);
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(BUCKET)
.key(uuid.toString())
.responseContentDisposition(contentDisposition)
.responseContentType(contentType)
.build();
GetObjectPresignRequest getObjectPresignRequest =
GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(5))
.getObjectRequest(getObjectRequest)
.build();
PresignedGetObjectRequest presignedGetObjectRequest =
s3Presigner.presignGetObject(getObjectPresignRequest);
return presignedGetObjectRequest.url().toString();
}
@GetMapping("/redirect/{uuid}")
public void redirectToS3(@PathVariable UUID uuid, HttpServletResponse response) {
try {
var URI = storageServiceS3.getPresignedURL(uuid);
response.sendRedirect(URI);
} catch (NoSuchKeyException | IOException e) {
response.setStatus(404);
}
}
它作業得很好;)
uj5u.com熱心網友回復:
@Алексеев станислав
為此,一些作業是通過 javascript 消耗您的休息服務,并在客戶端下載時在新的標頭回應中添加檔案名并重命名檔案。
// don't forget to allow X-File-Name header on CORS in spring
headers.add("X-File-Name", nameToBeDownloaded );
ANGULAR 示例,但可以決議為其他語言
this.http.get(uri_link_spring_redirecting_to_S3, {
responseType: 'blob',
observe: 'response'
}).subscribe(
(response) => {
var link = document.createElement('a');
var file = new Blob([response.body], {
type: 'text/csv;charset=utf-8;'
});
link.href = window.URL.createObjectURL(file);
link.download = response?.headers?.get('X-File-Name');; 'download.csv';
link.click();
},
error => {
...
}
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/376111.html
