Docker打包Java Lambda用SAM Local测试API报错及解决
AWS Lambda(Java + Docker + CDK)本地SAM测试报错及解决方法
问题背景
参考AWS文档实现Java编写的Lambda函数,打包为Docker镜像后通过AWS CDK部署为Lambda处理器,部署到AWS后运行正常,但使用AWS SAM Local测试时出现报错。
1. Java Lambda函数代码
package trial; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.util.Map; public class Handler implements RequestHandler<Map<String,Object>, String>{ Gson gson = new GsonBuilder().setPrettyPrinting().create(); @Override public String handleRequest(Map<String,Object> event, Context context) { LambdaLogger logger = context.getLogger(); String response = "200 OK"; // 记录执行详情 logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv())); logger.log("CONTEXT: " + gson.toJson(context)); // 处理事件 logger.log("EVENT: " + gson.toJson(event)); logger.log("EVENT TYPE: " + event.getClass().toString()); return response; } }
2. Dockerfile代码
FROM public.ecr.aws/lambda/java:11 COPY lib/* ${LAMBDA_TASK_ROOT}/lib/ CMD [ "trial.Handler::handleRequest" ]
3. AWS CDK部署代码
const repo = aws.aws_ecr.Repository.fromRepositoryArn( construct, "repoId", "arn:aws:ecr:eu-west-1:***ACCOUNTID***:repository/repo" ) const lambda1 = new aws.aws_lambda.DockerImageFunction(construct, "HelloFunction", { code: aws.aws_lambda.DockerImageCode.fromEcr(repo), }) const api = new aws.aws_apigateway.LambdaRestApi(construct, 'sample-api', { handler: lambda1 })
4. SAM Local测试命令
sam local start-api -t cdk.out/HelloCdkStack.template.json --warm-containers EAGER
5. 报错信息
"resourceId": "123456", "resourcePath": "/{proxy+}", "stage": "prod" }, "resource": "/{proxy+}", "version": "1.0" }EVENT TYPE: class java.util.LinkedHashMapEND RequestId: 9a7201d8-7b4b-486e-9208-2da9a8972347 REPORT RequestId: 9a7201d8-7b4b-486e-9208-2da9a8972347 Duration: 9.99 ms Billed Duration: 10 ms Memory Size: 128 MB Max Memory Used: 128 MB Invalid lambda response received: Lambda returned <class 'str'> instead of dict 2022-12-23 01:30:24 127.0.0.1 - - [23/Dec/2022 01:30:24] "GET /favicon.ico HTTP/1.1" 502 -
解决方法
Lambda处理器需返回符合API Gateway规范的Object类型(而非简单字符串),修改后的返回代码如下:
return Map.of( "statusCode", 200, "body", "test response", "headers", Map.of( "Content-Type", "application/json" ) );
内容的提问来源于stack exchange,提问作者Aleksand Kondaurov
相关产品推荐
相关产品推荐

