【发布时间】:2021-12-19 17:16:09
【问题描述】:
class DownloadFileHandler RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Overrider
public APIGatewayProxyResponseEvent handlerRequest(APIGatewayProxyRequestEvent event, Context context) {
String fileName = event.getQueryStringParameters().get("fileName");
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(Regions.US_EAST_2).build();
GetObjectRequest request = new GetObjectRequest(bucket, fileName);
S3Object objectFile = s3Client.getObject(request);
S3ObjectInputStream objectInputStream = objectFile.getObjectContent();
// latest I was trying this
byte [] fileBytes = new byte[0];
try {
fileBytes = objectInputStream.readAllBytes();
} catch (IOException e) {
e.printStackTrace();
}
}
Map<String, String> headers = new LinkedHashMap<>();
headers.put("Content-Type", "application/json");
headers.put("Accept", "application/octet-stream");
headers.put("Content-Disposition", String.format(Locale.UK, "attachment; filename=%s", fileName));
headers.put("Content-Length", String.valueOf(fileBytes.length));
// I tried this
JSONObject response = new JSONObject();
response.append("file", objectFile);
APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent()
.withHeaders(headers)
.withStatusCode(200)
.withIsBase64Encoded(true)
.withBody(Base64.getEncoder().encodeToString(fileBytes));
return responseEvent;
}
}
在上面的代码中,我有 requestHandler 从 AWS S3 提取文件,它应该将其作为响应发送。我在上面进行了编码,您可以看到我尝试了至少两种非工作方法。我的意思是我可以将文件作为字符串发送,但我无法下载此文件。我得到的不是文件内容,而是
DIxMTc1NSAwMDAwMCBuDQowMDAwMjExODg3IDAwMDAwIG4NCjAwMDAyMTE5MTQgMDAwMDAgbg0KMDAwMDIxMjM5MiAwMDAwMCBuDQowMDAwMjE3NDQ3IDAwMDAwIG4NCjAwMDAyMTc1MTcgMDAwMDAgbg0KMDAwMDIxNzc4MiAwMDAwMCBuDQowMDAwMjE3ODYzIDAwMDAwIG4NCjAwMDAyMzExMDAgMDAwMDAgbg0KMDAwMDIzMTEyNyAwMDAwMCBuDQowMDAwMjMxNTA5IDAwMDAwIG4NCjAwMDAyMzY2MDkgMDAwMDAgbg0KMDAwMDIzNjY3OSAwMDAwMCBuDQowMDAwMjM2OTUwIDAwMDAwIG4NCjAwMDAyMzcwMzEgMDAwMDAgbg0KMDAwMDI0NTA4NSAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDE2Ny9Sb290IDE4IDAgUi9JbmZvIDE2IDAgUi9JRFs8RTdCRDQzNDY0Mzg0Q0M0OTU1QTVBQTNBRTIzMzQxNUI+PDM5RDcyRDQ5OEJGMzFFNDhCMEQ5QjkxODBFOEIzQzVFPl0vUHJldiAyMDI0MzA+Pg0Kc3RhcnR4cmVmDQoyNDk0NDgNCiUlRU9GDQo=%
[content cut out]
所以我认为那是文件。但是由于某种原因我无法下载它,因为当我保存这个文件时它无法打开,我收到file damaged etc.
如果能帮助我理解为什么这种方法不起作用,我将不胜感激?我在 AWS 文档中找不到任何关于 Java 的示例。其中大部分是关于 Python 或 JavaScript 的。似乎我不理解它们,因为我看到了类似的代码
response = {
"statusCode" : 200,
"body" : file
}
或类似的东西。对我来说,这意味着我必须将文件包装到 JSON 对象中,然后从我的处理程序方法中返回它。但这对我不起作用,因为我得到了你可以在上面看到的 2 sn-p 代码。请解释我做错了什么以及我不理解什么?
【问题讨论】:
-
响应中的内容类型不会是 application/json。它将类似于 image/png 或 application/pdf,具体取决于您要发送其内容的文件。
-
从AWS S3下载时,为什么标题说是从AWS Lambda下载?顺便说一句,看起来数据是 base64 编码的。
-
@DavidConrad AWS Lambda 函数位于 API Gateway 后面,它将对象从 S3 下载到 API 客户端。因此,API 客户端通过 API Gateway 从 Lambda 下载,而 Lambda 从 S3 下载,然后将文件内容发送到客户端。除此之外,这不是一个理想的解决方案(Lambda 函数可以简单地创建一个预签名的 URL 并将客户端 302 重定向到该 URL)。
-
jarmod 你的建议听起来很合理,但是如果我想发送不同类型的 pdf、docx 等呢?我在 aws doc 中读到,您应该始终从处理程序返回 JSON。
标签: java amazon-web-services file aws-lambda