AWS Serverless请求异常排查:POST请求触发input.getBody()与input.getHttpMethod() NullPointerException
解决AWS Serverless POST请求中APIGatewayProxyRequestEvent的NullPointerException问题
你现在遇到的核心问题是Lambda函数处理API Gateway POST请求时,input.getHttpMethod()和input.getBody()频繁抛出NullPointerException,而且异常位置还发生了变化。结合你的代码和配置,我整理了几个关键的排查和修复方向:
1. 检查API Gateway的映射模板配置
你的API Gateway用了默认的「当没有模板匹配请求Content-Type标头时使用默认值」配置,但默认模板可能没有正确填充APIGatewayProxyRequestEvent所需的核心字段(比如httpMethod、body),导致Lambda收到的事件对象属性缺失甚至整体为null。
修复步骤:
- 进入API Gateway控制台,找到你的API和对应的POST方法
- 切换到集成请求标签,找到映射模板部分
- 确保为
application/json(你的请求Content-Type)添加正确的映射模板,模板内容如下:{ "body": "$input.json('$')", "httpMethod": "$context.httpMethod", "headers": { #foreach($header in $input.params().header.keySet()) "$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end #end }, "queryStringParameters": { #foreach($param in $input.params().querystring.keySet()) "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end #end }, "pathParameters": { #foreach($param in $input.params().path.keySet()) "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end #end } } - 保存配置并重新部署API,确保映射模板生效。
2. 代码层面添加防御性检查
即使配置正确,也可能存在异常请求导致的NPE,所以在代码里提前做null检查是很有必要的:
修改你的handleRequest方法:
@Override public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { // 首先检查input本身是否为null if (input == null) { APIGatewayProxyResponseEvent errorResponse = new APIGatewayProxyResponseEvent(); return errorResponse.withStatusCode(400).withBody("Invalid request: null event received"); } Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() .withHeaders(headers); AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient(); DynamoDBMapper mapper = new DynamoDBMapper(client); Shift shift; String output; // 检查httpMethod是否为null String httpMethod = input.getHttpMethod(); if (httpMethod == null) { return response.withStatusCode(400).withBody("Missing HTTP method in request"); } if (httpMethod.equalsIgnoreCase(HttpMethod.GET.name())) { shift = mapper.load(Shift.class, context.getAwsRequestId()); if (shift == null) { throw new ResourceNotFoundException("Resource not found"); } output = shift.toString(); } else if (httpMethod.equalsIgnoreCase(HttpMethod.POST.name())) { // 检查body是否为null或空字符串 String body = input.getBody(); if (body == null || body.trim().isEmpty()) { return response.withStatusCode(400).withBody("Request body cannot be empty"); } try { shift = new Shift(body); WorkSchedule workSchedule = new WorkSchedule(client); if (!workSchedule.isShiftPossible(shift)) { throw new ConditionalCheckFailedException("Conditional check failed"); } mapper.save(shift); output = "SHIFT SAVED"; } catch (com.google.gson.JsonSyntaxException e) { return response.withStatusCode(400).withBody("Invalid JSON format in request body"); } } else { output = "Unsupported operation"; } return response .withStatusCode(200) .withBody(output); }
3. 确认API Gateway的版本和事件类型
如果你的API是API Gateway v2(HTTP API),那么Lambda收到的事件类型应该是APIGatewayV2ProxyRequestEvent,而不是你当前使用的APIGatewayProxyRequestEvent。这会导致反序列化失败,input对象直接为null,从而调用input.getHttpMethod()时抛出NPE。
检查方法:
- 进入API Gateway控制台,确认你的API类型是REST API还是HTTP API
- 如果是HTTP API,需要修改Lambda的RequestHandler泛型:
public class App implements RequestHandler<APIGatewayV2ProxyRequestEvent, APIGatewayV2ProxyResponseEvent> { // 对应的handleRequest方法逻辑需要适配APIGatewayV2ProxyRequestEvent的API }
4. 验证请求的Content-Type标头
确保你的POST请求的Content-Type标头设置为application/json,否则API Gateway的映射模板不会触发,导致请求体无法被正确传递到Lambda,input.getBody()返回null。
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

