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

AWS Lambda Function URL调用返回502 Bad Gateway问题排查求助

Why You're Getting a 502 Bad Gateway with Lambda Function URLs

Alright, let's break down the root cause first: the event structure sent by Lambda Function URLs is completely different from the simple test event you used in the AWS Console.

When you test via the console, you're sending a flat Map<String,String> that matches your handler's input type perfectly. But when you trigger the function via a Function URL, Lambda sends a full API Gateway V2-style event that includes nested objects like headers, requestContext, and body—not just string values. The error Cannot deserialize instance of java.lang.String out of START_OBJECT token happens because the serializer is trying to turn the headers object into a String, which it can't do.


Fix 1: Use the Official Function URL Event Type

The cleanest solution is to use AWS's dedicated event class for Function URLs, APIGatewayV2HTTPEvent, which is built to parse this full event structure correctly.

Step 1: Add the Lambda Events Dependency

First, include the aws-lambda-java-events library in your project (adjust for Gradle if needed):

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-events</artifactId>
    <version>3.11.0</version> <!-- Use the latest stable version -->
</dependency>

Step 2: Update Your Handler Code

Rewrite your handler to accept APIGatewayV2HTTPEvent and return APIGatewayV2HTTPResponse (this gives you full control over the HTTP response):

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.HashMap;
import java.util.Map;

// Handler value: example.Handler
public class Handler implements RequestHandler<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse> {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    @Override
    public APIGatewayV2HTTPResponse handleRequest(APIGatewayV2HTTPEvent event, Context context) {
        LambdaLogger logger = context.getLogger();
        
        // Log the full event for debugging
        logger.log("Full Function URL Event: " + gson.toJson(event));
        
        // Extract query parameters (like your ?message=HelloWorld)
        String message = event.getQueryStringParameters().get("message");
        logger.log("Received message query param: " + message);
        
        // Extract the request body
        String requestBody = event.getBody();
        logger.log("Request body content: " + requestBody);
        
        // Build a proper HTTP response
        Map<String, String> responseHeaders = new HashMap<>();
        responseHeaders.put("Content-Type", "application/json");
        
        return APIGatewayV2HTTPResponse.builder()
                .withStatusCode(200)
                .withHeaders(responseHeaders)
                .withBody(gson.toJson(Map.of("status", "success", "messageReceived", message)))
                .build();
    }
}

Fix 2: Adjust to Use Map<String, Object> (No Extra Dependency)

If you don't want to add the Lambda Events library, you can change your handler's input type to Map<String, Object> instead of Map<String,String>. This lets the serializer parse nested objects as sub-maps instead of trying to force them into Strings.

Updated Handler Signature

public class Handler implements RequestHandler<Map<String, Object>, String>{

Example Code to Handle Nested Objects

@Override
public String handleRequest(Map<String, Object> event, Context context) {
    LambdaLogger logger = context.getLogger();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    
    logger.log("EVENT: " + gson.toJson(event));
    
    // Access nested headers as a Map
    Map<String, Object> headers = (Map<String, Object>) event.get("headers");
    logger.log("Request Headers: " + gson.toJson(headers));
    
    // Access query parameters
    Map<String, String> queryParams = (Map<String, String>) event.get("queryStringParameters");
    String message = queryParams.get("message");
    logger.log("Message from query params: " + message);
    
    return gson.toJson(Map.of("status", "200 OK", "message", message));
}

Key Notes to Remember

  • Console Test vs Function URL Event: The console test event is custom and flat—don't rely on it to validate Function URL behavior. Use the pre-built "API Gateway V2 Event" template in the console to test your function properly.
  • Response Format: If you're returning JSON, always set the Content-Type: application/json header (using APIGatewayV2HTTPResponse makes this easy) to avoid client-side parsing issues.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:02:49