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

Lambda代理集成下API Gateway调用Java Lambda遇Input value must not null报错

解决API Gateway Lambda代理集成的两个核心问题:输入为空与响应格式错误

看起来你遇到的是Lambda代理集成里很常见的输入解析和响应格式问题,结合你给的代码和错误信息,我帮你拆解下原因和具体解决方案:

问题1:Input value must not be null(IllegalArgumentException)

用API Gateway的Lambda代理集成时,API Gateway不会直接把请求体传给Lambda,而是会把整个请求封装成一个标准的代理请求对象,结构大概是这样:

{
  "resource": "/your-path",
  "httpMethod": "POST",
  "body": "{\"id\":\"123\",\"firstName\":\"John\",...}",
  "headers": {...},
  // 其他请求元数据字段
}

而你的Handler直接用PersonRequest作为输入参数,Lambda没办法把这个代理请求对象反序列化成PersonRequest,导致personRequest(或者你代码里的userRequest)为null,后续调用personRequest.getId()就抛出了空值相关的异常。

另外,你的代码里还有明显的变量名笔误:Handler的参数是UserRequest userRequest,但代码里却用了personRequest(比如saveData(personRequest)、personRequest.getId()),这也会直接导致变量未定义或者空值问题。

问题2:Malformed Lambda proxy response

Lambda代理集成要求返回的响应必须严格符合以下格式,缺一不可:

{
  "isBase64Encoded": false,
  "statusCode": 200,
  "headers": {...},
  "body": "string"
}

你的代码在catch块里只打印了错误,没有对responseJson做任何错误填充,导致返回的JSON可能缺少必要字段,触发格式错误。同时,如果正常流程中saveData或者getItem抛出异常,也会跳过响应字段的填充,返回不完整的JSON。


修正后的解决方案代码

下面是调整后的完整代码,解决了上述所有问题:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import org.json.JSONObject;
import java.util.Map;

public class SavePersonHandler implements RequestHandler<Map<String, Object>, JSONObject> {
    private DynamoDB dynamoDb;
    private final String DYNAMODB_TABLE_NAME = "XXXX";
    private final Regions REGION = Regions.US_WEST_2;

    private void initDynamoDbClient() {
        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withRegion(REGION)
                .build();
        this.dynamoDb = new DynamoDB(client);
    }

    @Override
    public JSONObject handleRequest(Map<String, Object> proxyRequest, Context context) {
        LambdaLogger logger = context.getLogger();
        JSONObject responseJson = new JSONObject();
        
        try {
            this.initDynamoDbClient();
            
            // 1. 解析API Gateway代理请求中的body,转换成PersonRequest
            String requestBody = (String) proxyRequest.get("body");
            if (requestBody == null || requestBody.isEmpty()) {
                throw new IllegalArgumentException("Request body cannot be null or empty");
            }
            JSONObject bodyJson = new JSONObject(requestBody);
            PersonRequest personRequest = new PersonRequest();
            personRequest.setId(bodyJson.getString("id"));
            personRequest.setFirstName(bodyJson.getString("firstName"));
            personRequest.setLastName(bodyJson.getString("lastName"));
            personRequest.setAge(bodyJson.getInt("age"));
            personRequest.setAddress(bodyJson.getString("address"));
            
            // 2. 保存数据到DynamoDB
            saveData(personRequest);
            
            // 3. 查询并构建成功响应
            Item item = this.dynamoDb.getTable(DYNAMODB_TABLE_NAME)
                    .getItem("id", personRequest.getId(), "id, firstName, lastName, age, address", null);
            
            JSONObject responseBody = new JSONObject();
            responseBody.put("message", "Saved Successfully-" + item.toJSON());
            
            JSONObject headerJson = new JSONObject();
            headerJson.put("x-custom-header", "custom header value");
            
            responseJson.put("isBase64Encoded", false);
            responseJson.put("statusCode", 200);
            responseJson.put("headers", headerJson);
            responseJson.put("body", responseBody.toString());
            
        } catch (Exception e) {
            logger.log("Error occurred: " + e.getMessage());
            
            // 异常情况下也要返回符合格式的错误响应
            JSONObject errorBody = new JSONObject();
            errorBody.put("errorMessage", e.getMessage());
            errorBody.put("errorType", e.getClass().getName());
            
            responseJson.put("isBase64Encoded", false);
            responseJson.put("statusCode", 500);
            responseJson.put("headers", new JSONObject().put("Content-Type", "application/json"));
            responseJson.put("body", errorBody.toString());
        }
        
        return responseJson;
    }

    // 实现你的saveData方法
    private void saveData(PersonRequest personRequest) {
        Item item = new Item()
                .withPrimaryKey("id", personRequest.getId())
                .withString("firstName", personRequest.getFirstName())
                .withString("lastName", personRequest.getLastName())
                .withInt("age", personRequest.getAge())
                .withString("address", personRequest.getAddress());
        this.dynamoDb.getTable(DYNAMODB_TABLE_NAME).putItem(item);
    }

    // 你的PersonRequest实体类
    public static class PersonRequest {
        private String id;
        private String firstName;
        private String lastName;
        private int age;
        private String address;
        
        // getter和setter方法
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        public String getFirstName() { return firstName; }
        public void setFirstName(String firstName) { this.firstName = firstName; }
        public String getLastName() { return lastName; }
        public void setLastName(String lastName) { this.lastName = lastName; }
        public int getAge() { return age; }
        public void setAge(int age) { this.age = age; }
        public String getAddress() { return address; }
        public void setAddress(String address) { this.address = address; }
    }
}

关键修改点说明

  1. 输入参数类型调整:把RequestHandler<PersonRequest, JSONObject>改成RequestHandler<Map<String, Object>, JSONObject>,这样能接收API Gateway传过来的完整代理请求对象。
  2. 请求体手动解析:从代理请求的body字段中提取JSON字符串,手动转换成PersonRequest对象,避免自动反序列化失败的问题。
  3. 变量名统一修正:把代码里的变量名统一成personRequest,解决原代码中变量名不一致的笔误。
  4. 异常处理完善:在catch块中构建符合格式的错误响应,确保无论成功还是失败,返回的JSON都包含代理集成要求的所有字段。
  5. 响应格式严格对齐:确保返回的responseJson始终包含isBase64Encoded、statusCode、headers和body四个必填字段。

测试的时候,记得在API Gateway的测试界面中,把请求体写成标准JSON格式(比如{"id":"1","firstName":"Alice","lastName":"Smith","age":30,"address":"123 Main St"}),这样Lambda才能正确解析。

内容的提问来源于stack exchange,提问作者user3567195

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:01:23