AWS Lambda触发S3事件时input.body为空问题求助
问题分析与解决方案
你遇到的核心问题是触发Lambda的事件类型和代码预期不匹配,导致input.body为null,分两种情况拆解:
1. 直接用S3触发Lambda(而非API Gateway中转)
这种情况下,Lambda收到的原生事件是S3Event类型,不是APIGatewayProxyRequestEvent,所以代码里的input.body自然是空的——因为S3触发的事件根本不会走API Gateway的请求体结构。
修改方案:把Lambda的输入参数类型换成S3Event,直接从事件对象里取桶名,不用解析JSON字符串:
import com.amazonaws.services.lambda.runtime.events.S3Event import com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification import com.fasterxml.jackson.databind.ObjectMapper import com.amazonaws.services.lambda.runtime.Context import com.amazonaws.services.lambda.runtime.RequestHandler import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent class YourLambdaHandler : RequestHandler<S3Event, APIGatewayProxyResponseEvent> { private val objectMapper = ObjectMapper() override fun handleRequest(input: S3Event, context: Context): APIGatewayProxyResponseEvent { val response = APIGatewayProxyResponseEvent() try { val s3Record = input.records.firstOrNull()?.s3 ?: run { response.statusCode = 400 return response } val bucketName = s3Record.bucket.name val jsonResponse = objectMapper.writeValueAsString(mapOf("message" to bucketName)) response.statusCode = 200 response.body = jsonResponse } catch (e: Exception) { response.statusCode = 500 } return response } }
2. 通过API Gateway中转S3事件(比如S3把通知发到API Gateway,再触发Lambda)
这种情况下要检查两个点:
- 测试事件结构是否正确:部署后的测试事件必须是完整的
APIGatewayProxyRequestEvent结构,要把你本地用的S3事件内容放到body字段里;如果body是base64编码的,要把isBase64Encoded设为true,代码里要先解码:val body = if (input.isBase64Encoded) { String(java.util.Base64.getDecoder().decode(input.body)) } else { input.body } - API Gateway集成配置:确保API Gateway的集成请求没有丢弃请求体,比如
POST方法的集成设置要保留请求体传递逻辑。
额外提示
本地测试时你用的是模拟的API Gateway事件,所以代码能正常解析,但部署后如果触发源变了(比如直接S3触发),事件结构完全不同,就会出现body为空的情况。先确认你的Lambda触发源到底是哪种,再对应调整代码或配置。
内容的提问来源于stack exchange,提问作者Phrixus
相关产品推荐
相关产品推荐

