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

如何在AWS Lambda上的Spring Cloud Function中获取请求路径

问题描述

我能从Lambda Function URL的传入请求中获取主机、查询参数、请求头等信息,但**请求路径(比如xxx.lambda-url.us-west-2.on.aws/example中的/example)**始终缺失。

当前使用的Lambda处理器为:org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest,函数代码如下:

public Function<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> handleRequest() {
    return value -> {
        APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent();
        responseEvent.setStatusCode(200);
        responseEvent.setHeaders(Collections.singletonMap("Content-Type", "text/plain"));
        responseEvent.setBody(value.toString());
        return responseEvent;
    };
}

我也尝试过使用Message<String>作为输入,但依然无法获取请求路径。

示例响应(路径相关字段缺失):

{version: 2.0,headers: {content-length=5, x-amzn-tls-version=TLSv1.2, x-forwarded-proto=https, postman-token=63fb055b-b7a9-4118-bd65-b3871178feba, x-forwarded-port=443, x-api-token=123456, accept=* /*, x-amzn-tls-cipher-suite=ECDHE-RSA-AES128-GCM-SHA256, x-amzn-trace-id=Root=1-62e0b85d-37132a0f191aa55604dc8ed3, host=xxx.lambda-url.us-west-2.on.aws, content-type=text/plain, cache-control=no-cache, accept-encoding=gzip, deflate, br, user-agent=PostmanRuntime/7.29.2},queryStringParameters: {param1=true},requestContext: {accountId: anonymous,stage: $default,requestId: 82277194-0d8c-4edc-b5b8-7ad35ca62e76,apiId: xxx,},isBase64Encoded: false}

查看Lambda原始传入事件,能看到rawPath和requestContext.http.path字段,但APIGatewayProxyRequestEvent无法映射这些字段:

{
    "version": "2.0",
    "routeKey": "$default",
    "rawPath": "/testing",
    "rawQueryString": "hello=true",
    "headers": { "removed for brevity" },
    "queryStringParameters": {
        "hello": "true"
    },
    "requestContext": {
        "accountId": "anonymous",
        "apiId": "xxx",
        "domainName": "xxx.lambda-url.us-west-2.on.aws",
        "domainPrefix": "xxx",
        "http": {
            "method": "GET",
            "path": "/testing",
            "protocol": "HTTP/1.1",
            "sourceIp": "151.210.174.210",
            "userAgent": "PostmanRuntime/7.29.2"
        },
        "requestId": "bc27912e-672f-48e3-bf6d-84b28da74431",
        "routeKey": "$default",
        "stage": "$default",
        "time": "27/Jul/2022:20:46:42 +0000",
        "timeEpoch": 1658954802798
    },
    "isBase64Encoded": false
}

使用的依赖版本:

  • aws-lambda-java-core 1.2.1
  • aws-lambda-java-events 3.11
  • spring-cloud-function-adapter-aws 3.2.6

解决方案

问题核心是Lambda Function URL的事件格式与APIGatewayProxyRequestEvent不兼容:前者是Lambda原生的Function URL事件结构,而APIGatewayProxyRequestEvent是为API Gateway设计的模型,无法映射Function URL特有的rawPath和requestContext.http字段。可通过以下方式解决:

1. 自定义POJO映射完整事件

创建匹配Function URL事件结构的POJO,直接接收原始事件:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;

public class FunctionUrlHandler implements RequestHandler<FunctionUrlRequest, APIGatewayProxyResponseEvent> {
    @Override
    public APIGatewayProxyResponseEvent handleRequest(FunctionUrlRequest input, Context context) {
        // 获取路径信息
        String rawPath = input.getRawPath();
        String httpPath = input.getRequestContext().getHttp().getPath();
        
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        response.setStatusCode(200);
        response.setHeaders(Map.of("Content-Type", "text/plain"));
        response.setBody("Raw Path: " + rawPath + "\nHTTP Path: " + httpPath);
        return response;
    }

    // 匹配事件结构的内部类
    public static class FunctionUrlRequest {
        private String version;
        private String routeKey;
        private String rawPath;
        private String rawQueryString;
        private Map<String, String> headers;
        private Map<String, String> queryStringParameters;
        private RequestContext requestContext;
        private boolean isBase64Encoded;

        // Getters and Setters
        public String getRawPath() { return rawPath; }
        public void setRawPath(String rawPath) { this.rawPath = rawPath; }
        public RequestContext getRequestContext() { return requestContext; }
        public void setRequestContext(RequestContext requestContext) { this.requestContext = requestContext; }

        public static class RequestContext {
            private String accountId;
            private String apiId;
            private Http http;

            // Getters and Setters
            public Http getHttp() { return http; }
            public void setHttp(Http http) { this.http = http; }

            public static class Http {
                private String method;
                private String path;

                // Getters and Setters
                public String getPath() { return path; }
                public void setPath(String path) { this.path = path; }
            }
        }
        // 其他字段的getter/setter省略
    }
}

2. 使用Map<String, Object>接收原始事件

如果不想定义POJO,可直接用Map<String, Object>接收事件,通过键值对获取路径:

public Function<Map<String, Object>, APIGatewayProxyResponseEvent> handleRequest() {
    return input -> {
        // 获取rawPath
        String rawPath = (String) input.get("rawPath");
        // 从requestContext.http中获取path
        Map<String, Object> requestContext = (Map<String, Object>) input.get("requestContext");
        Map<String, Object> http = (Map<String, Object>) requestContext.get("http");
        String httpPath = (String) http.get("path");

        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        response.setStatusCode(200);
        response.setHeaders(Collections.singletonMap("Content-Type", "text/plain"));
        response.setBody("Raw Path: " + rawPath + "\nHTTP Path: " + httpPath);
        return response;
    };
}

3. 升级依赖使用官方适配类

aws-lambda-java-events从3.12.0版本开始,新增了FunctionUrlRequestEvent类,专门用于处理Lambda Function URL事件。升级依赖后直接使用该类:

<!-- Maven依赖示例 -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-events</artifactId>
    <version>3.12.0</version>
</dependency>

函数代码修改为:

public Function<FunctionUrlRequestEvent, APIGatewayProxyResponseEvent> handleRequest() {
    return input -> {
        String rawPath = input.getRawPath();
        String httpPath = input.getRequestContext().getHttp().getPath();
        
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        response.setStatusCode(200);
        response.setHeaders(Collections.singletonMap("Content-Type", "text/plain"));
        response.setBody("Raw Path: " + rawPath + "\nHTTP Path: " + httpPath);
        return response;
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 04:15:44