使用aws无服务器java容器和springboot2时如何提供zip文件?

wqlqzqxt  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(296)

我在aws无服务器java容器中使用streamlambdahandler创建一个restapi作为aws lambda函数。它被设置为在使用lambda代理集成的api网关api后面运行( /{proxy+} - ANY - Method Execution ).
一切正常,但我有一个@controller路由,应该返回一个zip文件(二进制数据)。
不管我在尝试什么,我得到的只是一个base64编码的响应体。粘贴下面api网关中测试调用的日志。在浏览器中运行url时,它会下载一个文件 foo.zip 但它实际上不是zip文件,而是:

> file foo.zip
> foo.zip: ASCII text, with CRLF line terminators

在api网关中,我添加了 */* 低于 Settings > Binary Media Types 如前所述。更新:在此步骤之后部署api Resources > Actions > Deploy API 我错过了什么?下面是一些代码:
pojo(简体)

public final class LicenseEntity {
    public String name;
    public byte[] content;
}

控制器代码

defaultHeaders = new HttpHeaders();
        defaultHeaders.add("X-Requested-With", "*");
        defaultHeaders.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
        defaultHeaders.add("Access-Control-Allow-Headers", "Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with");

    @RequestMapping(value = "/download/licenses/{licenseId}", produces="application/zip")
    public ResponseEntity<StreamingResponseBody> download(@PathVariable("licenseId") String licenseId) {
        // left out
        return createResponseEntity(..);
   }

    private ResponseEntity<StreamingResponseBody> createResponseEntity(List<LicenseEntity> entities) {
        var zipFileHeaders = new HttpHeaders();
        for (String keyName: defaultHeaders.keySet()) {
            zipFileHeaders.add(keyName, defaultHeaders.getFirst(keyName));
        }

        zipFileHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=foo.zip");
        zipFileHeaders.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");

        return ResponseEntity
                .ok()
                .headers(zipFileHeaders)
                .body(out -> {
                    try (var zipOutputStream = new ZipOutputStream(out);) {
                        for (LicenseEntity entity : entities) {
                            try (InputStream inputStream = new ByteArrayInputStream(entity.content);) {
                                zipOutputStream.putNextEntry(new ZipEntry(entity.name));
                                IOUtils.copy(inputStream, zipOutputStream);
                            }
                            zipOutputStream.closeEntry();
                        }
                    }
                });
    }

api网关日志

Execution log for request 478b0d95-a8db-41e9-8382-0de77ec54cc0
Thu Nov 19 16:31:11 UTC 2020 : Starting execution for request: 478b0d95-a8db-41e9-8382-0de77ec54cc0
Thu Nov 19 16:31:11 UTC 2020 : HTTP Method: GET, Resource Path: /v1/download/licenses/9d53f58e-ec14-4d3e-b93f-a014a0a01b5a
Thu Nov 19 16:31:11 UTC 2020 : Method request path: {proxy=v1/download/licenses/9d53f58e-ec14-4d3e-b93f-a014a0a01b5a}
Thu Nov 19 16:31:11 UTC 2020 : Method request query string: {}
Thu Nov 19 16:31:11 UTC 2020 : Method request headers: {}
Thu Nov 19 16:31:11 UTC 2020 : Method request body before transformations: 
Thu Nov 19 16:31:11 UTC 2020 : Endpoint request URI: https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:ACCOUNTID:function:FUNCTIONNAME/invocations
Thu Nov 19 16:31:11 UTC 2020 : Endpoint request headers: {x-amzn-lambda-integration-tag=478b0d95-a8db-41e9-8382-0de77ec54cc0, Authorization=************************************************************************************************************************************************************************************************************************************************************************************************************************f22b2b, X-Amz-Date=20201119T163111Z, x-amzn-apigateway-api-id=HASHCODE, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-1:ACCOUNTID:HASHCODE/test-invoke-stage/GET/{proxy+}, Accept=application/json, User-Agent=AmazonAPIGateway_HASHCODE, X-Amz-Security-Token=IQoJb3JpZ2luX2VjEOj//////////wEaCWV1LXdlc3QtMSJGMEQCIDBqxIr89XxH+0xD/MjXhenc3o4h18uZk9dmaifikAkaAiBLInRUvlJrH8Jp7esPn2NO7CzGkNow05ysMS5RaDSy/iq0AwhhEAEaDDYzMTE0NDAwMjA5OSIMl1iChMw1yeXx/oyCKpED/P/jygty9Mud/QVn5b2o3mLBDppbiy9Ns5X2LLTEckvy/azM6HL+25vBvnB3zJVBahBP369P44UYmPBAa1UniayEX0Kk3oa6sJgDHY9X4O6Dt09NYsUykIBfPxJS0F5uhdjGGNKEUNdKV8zTf0GZ [TRUNCATED]
Thu Nov 19 16:31:11 UTC 2020 : Endpoint request body after transformations: {"resource":"/{proxy+}","path":"/v1/download/licenses/9d53f58e-ec14-4d3e-b93f-a014a0a01b5a","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":{"proxy":"v1/download/licenses/9d53f58e-ec14-4d3e-b93f-a014a0a01b5a"},"stageVariables":null,"requestContext":{"resourceId":"md5zfv","resourcePath":"/{proxy+}","httpMethod":"GET","extendedRequestId":"WQ2YgFwcjoEFVvQ=","requestTime":"19/Nov/2020:16:31:11 +0000","path":"/{proxy+}","accountId":"ACCOUNTID","protocol":"HTTP/1.1","stage":"test-invoke-stage","domainPrefix":"testPrefix","requestTimeEpoch":1605803471936,"requestId":"478b0d95-a8db-41e9-8382-0de77ec54cc0","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"arn:aws:iam::ACCOUNTID:user/NAME","apiKeyId":"test-invoke-api-key-id","userAgent":"aws-internal/3 aws- [TRUNCATED]
Thu Nov 19 16:31:11 UTC 2020 : Sending request to https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:ACCOUNTID:function:FUNCTIONNAME/invocations
Thu Nov 19 16:31:12 UTC 2020 : Received response. Status: 200, Integration latency: 177 ms
Thu Nov 19 16:31:12 UTC 2020 : Endpoint response headers: {Date=Thu, 19 Nov 2020 16:31:12 GMT, Content-Type=application/json, Content-Length=946, Connection=keep-alive, x-amzn-RequestId=1f12b2ae-2bc6-4a57-a1a3-cbf15fb48a2b, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-5fb69dcf-d3d8068ef93ecbbd68717aef;sampled=0}
Thu Nov 19 16:31:12 UTC 2020 : Endpoint response body before transformations: {"statusCode":200,"multiValueHeaders":{"Access-Control-Allow-Headers":["Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with"],"Access-Control-Allow-Methods":["GET, POST, DELETE, PUT, PATCH, OPTIONS"],"Content-Disposition":["attachment; filename=foo.zip"],"Content-Type":["application/octet-stream"],"Vary":["Origin","Access-Control-Request-Method","Access-Control-Request-Headers"],"X-Requested-With":["*"]},"body":"UEsDBBQACAgIAOaDc1EAAAAAAAAAAAAAAAAFAAAAMC50eHTLSM3JyQcAUEsHCIamEDYHAAAABQAA\r\nAFBLAwQUAAgICADmg3NRAAAAAAAAAAAAAAAABQAAADEudHh0y0jNyckHAFBLBwiGphA2BwAAAAUA\r\nAABQSwMEFAAICAgA5oNzUQAAAAAAAAAAAAAAAAUAAAAyLnR4dMtIzcnJBwBQSwcIhqYQNgcAAAAF\r\nAAAAUEsBAhQAFAAICAgA5oNzUYamEDYHAAAABQAAAAUAAAAAAAAAAAAAAAAAAAAAADAudHh0UEsB\r\nAhQAFAAICAgA5oNzUYamEDYHAAAABQAAAAUAAAAAAAAAAAAAAAAAOgAAADEudHh0UEsBAhQAFAAI\r\nCAgA5oNzUYamEDYHAAAABQAAAAUAAAAAAAAAAAAAAAAAdAAAADIudHh0UEsFBgAAAAADAAMAmQAA\r\nAK4AAAAAAA==","isBase64Encoded":true}
Thu Nov 19 16:31:12 UTC 2020 : Method response body after transformations: UEsDBBQACAgIAOaDc1EAAAAAAAAAAAAAAAAFAAAAMC50eHTLSM3JyQcAUEsHCIamEDYHAAAABQAA
AFBLAwQUAAgICADmg3NRAAAAAAAAAAAAAAAABQAAADEudHh0y0jNyckHAFBLBwiGphA2BwAAAAUA
AABQSwMEFAAICAgA5oNzUQAAAAAAAAAAAAAAAAUAAAAyLnR4dMtIzcnJBwBQSwcIhqYQNgcAAAAF
AAAAUEsBAhQAFAAICAgA5oNzUYamEDYHAAAABQAAAAUAAAAAAAAAAAAAAAAAAAAAADAudHh0UEsB
AhQAFAAICAgA5oNzUYamEDYHAAAABQAAAAUAAAAAAAAAAAAAAAAAOgAAADEudHh0UEsBAhQAFAAI
CAgA5oNzUYamEDYHAAAABQAAAAUAAAAAAAAAAAAAAAAAdAAAADIudHh0UEsFBgAAAAADAAMAmQAA
AK4AAAAAAA==
Thu Nov 19 16:31:12 UTC 2020 : Method response headers: {Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with, Access-Control-Allow-Methods=GET, POST, DELETE, PUT, PATCH, OPTIONS, Content-Disposition=attachment; filename=foo.zip, Content-Type=application/octet-stream, Vary=Origin,Access-Control-Request-Method,Access-Control-Request-Headers, X-Requested-With=*, X-Amzn-Trace-Id=Root=1-5fb69dcf-d3d8068ef93ecbbd68717aef;Sampled=0}
Thu Nov 19 16:31:12 UTC 2020 : Successfully completed execution
Thu Nov 19 16:31:12 UTC 2020 : Method completed with status: 200

更新

在添加二进制媒体类型之后,我从未重新部署我的api网关api。显然,这是必须要做的,为了让变化出来。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题