You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:27:40