Java AWS Lambda被EventBridge触发时无法获取事件payload的问题
问题原因
你当前的Lambda函数用APIGatewayProxyRequestEvent作为输入参数,这个类是专门为API Gateway的LAMBDA_PROXY集成设计的,和EventBridge触发时传递的事件结构完全不匹配。EventBridge的事件不会填充APIGatewayProxyRequestEvent里的body字段,所以你拿到的input.getBody()自然是null。
解决方案
下面提供几种可行的处理方式:
1. 用通用类型接收事件(推荐,适配多触发源)
把输入参数改成Object或者Map<String, Object>,这样能接收任意格式的事件,再根据触发源判断并解析:
@Override public APIGatewayProxyResponseEvent handleRequest(Object input, Context context) { // 先打印原始事件,确认结构 logger.info("Raw event: {}", input.toString()); // 处理EventBridge事件 if (input instanceof Map) { Map<String, Object> eventMap = (Map<String, Object>) input; // 如果是EventBridge封装的事件,payload在detail字段;如果是你直接传的自定义JSON,直接读map即可 Object payload = eventMap.getOrDefault("detail", eventMap); logger.info("EventBridge payload: {}", payload); } // 处理API Gateway请求 else if (input instanceof APIGatewayProxyRequestEvent) { APIGatewayProxyRequestEvent apiEvent = (APIGatewayProxyRequestEvent) input; logger.info("API Gateway body: {}", apiEvent.getBody()); } // 后续业务逻辑... return new APIGatewayProxyResponseEvent().withStatusCode(200); }
2. 自定义EventBridge事件类
创建对应EventBridge事件结构的Java类,用Jackson解析:
import com.fasterxml.jackson.databind.ObjectMapper; // 匹配EventBridge事件结构的自定义类 public class EventBridgeEvent { private String version; private String id; private String detailType; private String source; private Map<String, Object> detail; // 存放你的自定义payload // 生成getter、setter方法 } // Lambda处理逻辑 @Override public APIGatewayProxyResponseEvent handleRequest(Object input, Context context) { ObjectMapper objectMapper = new ObjectMapper(); try { // 尝试解析为EventBridge事件 EventBridgeEvent ebEvent = objectMapper.convertValue(input, EventBridgeEvent.class); logger.info("EventBridge payload: {}", ebEvent.getDetail()); } catch (IllegalArgumentException e) { // 解析失败,说明是API Gateway请求 APIGatewayProxyRequestEvent apiEvent = objectMapper.convertValue(input, APIGatewayProxyRequestEvent.class); logger.info("API Gateway body: {}", apiEvent.getBody()); } // 后续业务逻辑... return new APIGatewayProxyResponseEvent().withStatusCode(200); }
3. 用InputStream读取原始事件
如果上面的方式有问题,直接读取原始输入流再手动反序列化:
import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import java.io.InputStream; import java.io.OutputStream; import com.fasterxml.jackson.databind.ObjectMapper; public class MyLambdaHandler implements RequestStreamHandler { private final ObjectMapper objectMapper = new ObjectMapper(); private final Logger logger = Logger.getLogger(MyLambdaHandler.class.getName()); @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) { try { // 读取原始事件字符串 String rawEvent = new String(inputStream.readAllBytes()); logger.info("Raw event: {}", rawEvent); // 根据特征判断事件类型 if (rawEvent.contains("detailType")) { EventBridgeEvent ebEvent = objectMapper.readValue(rawEvent, EventBridgeEvent.class); logger.info("EventBridge payload: {}", ebEvent.getDetail()); } else { APIGatewayProxyRequestEvent apiEvent = objectMapper.readValue(rawEvent, APIGatewayProxyRequestEvent.class); logger.info("API Gateway body: {}", apiEvent.getBody()); } // 返回响应 APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent().withStatusCode(200); objectMapper.writeValue(outputStream, response); } catch (Exception e) { logger.error("处理请求出错", e); } } }
关键注意点
- EventBridge触发Lambda时,默认事件会包含
version、id、detail等字段,你的自定义payload在detail里;如果是直接配置的自定义JSON(没有EventBridge封装),事件就是你传入的JSON本身。 - 要让Lambda同时支持API Gateway和EventBridge触发,必须用通用输入类型,不能只绑定
APIGatewayProxyRequestEvent。
内容的提问来源于stack exchange,提问作者Paul Chuang
相关产品推荐
相关产品推荐

