并非完全自定义,但您可以向内容添加元标记。比如:
Map<String, String> metadata = new HashMap<>();
metadata.put("x-amz-meta-my-cool-header", "woohoo");
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(fileObjKeyName)
.metadata(metadata)
.build();
结果:
元数据键必须以x-amz-meta-开头。请参阅Working with object metadata 了解更多详细信息。
更新
由于您必须固定标头,因此一种方法是在 S3 前面放置一个 Lambda 和 API 网关。它充当代理。这会有点贵,因为现在您正在从 S3 读取数据、启动 Lambda 并通过 API 网关。但我能够得到一些代码来工作。重要的部分(一个 Java Lambda,因为这就是您开始使用的)。这使用JsonPath 从请求中读取文件名:
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
LambdaLogger logger = context.getLogger();
String fileName = JsonPath.read(inputStream, "$.pathParameters.fileName");
try {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
APIGatewayResponse apiGatewayResponse = new APIGatewayResponse();
apiGatewayResponse.setBase64Encoded(Boolean.TRUE);
ResponseBytes<GetObjectResponse> getObjectResponseResponseBytes = s3Client.getObject(getObjectRequest, ResponseTransformer.toBytes());
apiGatewayResponse.setBody(Base64.getEncoder().encodeToString(getObjectResponseResponseBytes.asByteArray()));
apiGatewayResponse.setStatusCode(200);
apiGatewayResponse.addHeader("Content-Type", getObjectResponseResponseBytes.response().contentType());
if( getObjectResponseResponseBytes.response().metadata().get("my-cool-header") != null ) {
apiGatewayResponse.addHeader("Content-Description", getObjectResponseResponseBytes.response().metadata().get("my-cool-header"));
}
String outputString = objectMapper.writeValueAsString(apiGatewayResponse);
logger.log("output is \"" + outputString + "\"");
outputStream.write(outputString.getBytes(StandardCharsets.UTF_8));
}
catch( ...
它从 S3 读取指定的文件,如果存在特定的标头,它将作为 API 网关标头发送回。请注意,即使您必须将标头存储在 S3 中以 x-amz-meta- 开头的对象上,但它会在没有它的情况下返回。
我在前面放了一个 API 网关,重要的部分是:
"/s3proxy/{fileName}" : {
"get" : {
"responses" : {
"default" : {
"description" : "Default response for GET /s3proxy/{fileName}"
}
},
"x-amazon-apigateway-integration" : {
"payloadFormatVersion" : "2.0",
"type" : "aws_proxy",
"httpMethod" : "POST",
"uri" : "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:1234567890:function:s3proxy/invocations",
"connectionType" : "INTERNET"
}
}
}
我会说 API 网关对我来说是 80% 的魔法,我很可能错过了一些东西。例如,我将此设置为 GET,而导出显示为 POST。
显然这里有工作要做,Java 可能不是文件服务器服务的最佳解决方案,因为冷启动在 512MB Lambda 上大约需要 9 秒,在 2048MB 上大约需要 4 秒。但它会做你想做的事,今天下午很好地分散了注意力:)