【问题标题】:How can I add a custom header via PutObjectRequestBuilder in AWS Java SDK v2?如何通过 AWS Java SDK v2 中的 PutObjectRequestBuilder 添加自定义标头?
【发布时间】:2021-03-16 17:22:09
【问题描述】:

我在 AWS Java SDK v2 中使用 PutObjectRequestBuilder (https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/PutObjectRequest.Builder.html) 将文件从我的计算机传输到可公开访问的 AWS S3 存储桶,其他人和软件最终将从那里下载该文件。 PutObjectRequestBuilder 允许我设置将放在发送给这些人的 HTTP 响应的标头中的各种内容,例如 contentType(String contentType) 让我指定将在标头中的 Content-Type 标记中指定的 MIME 类型回复。但我还需要为一些将下载这些文件的客户端软件所需的标题指定一些非标准项目(例如,“Content-Description”=“dods-das”)。不幸的是,我在 PutObjectRequestBuilder 中没有看到添加自定义标头的方法。有没有办法指定自定义标题项?

【问题讨论】:

    标签: java amazon-web-services http amazon-s3 sdk


    【解决方案1】:

    并非完全自定义,但您可以向内容添加元标记。比如:

    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 秒。但它会做你想做的事,今天下午很好地分散了注意力:)

    【讨论】:

    • 谢谢。很高兴知道,但这并不能解决我的问题。我不能在标题中使用例如 x-amz-meta-Content-Description。例如,它必须是 Content-Description 才能与我必须使用的其他系统一起使用。我需要能够指定确切的标签名称。
    • 另一种可能性@BobSimons-NOAAFederal 现在在我更新的帖子中。
    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 2018-06-22
    • 2020-05-10
    相关资源
    最近更新 更多