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

使用AWS SDK调用Lambda Function URL时触发NullPointerException

Java调用Lambda Function URL签名失败问题排查

我正尝试在Java应用中通过Function URL调用AWS Lambda函数,使用Java AWS SDK 2.18.7对请求进行签名,但始终无法成功。我拥有具备Lambda Function URL执行权限的用户的访问密钥和秘密密钥。

代码在第150行Response awsResponse = reb.execute();处崩溃,代码如下:

Request<Void> request = new DefaultRequest<Void>("lambda");
request.setHttpMethod(HttpMethodName.POST);
request.setEndpoint(URI.create(this.LAMBDA_URL));
request.setContent(new ByteArrayInputStream(postJsonString.getBytes(StandardCharsets.UTF_8)));
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Length", Integer.toString(postJsonString.length()));
request.setHeaders(headers);
// Sign AWS Request
AWS4Signer signer = new AWS4Signer();
signer.setRegionName(MY_REGION);
signer.setServiceName(request.getServiceName());
BasicAWSCredentials awsCreds = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
signer.sign(request, awsCreds);
// Execute and get response
ClientConfiguration config = new ClientConfiguration();
AmazonHttpClient client = new AmazonHttpClient(config);
RequestExecutionBuilder reb = client.requestExecutionBuilder();
reb = reb.request(request);
reb = reb.executionContext(new ExecutionContext());
Response<Void> awsResponse = reb.execute();

控制台输出的异常信息:

Exception in thread "main" java.lang.NullPointerException
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1879)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1418)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1387)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1157)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:814)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:781)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:755)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:715)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:697)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:702)
    at aws_auth_awssdk2_18_7.Main.aws_sdk_attemp(Main.java:150)
    at aws_auth_awssdk2_18_7.Main.main(Main.java:67)

问题根源与修复方案

  1. SDK版本混淆
    你使用的是AWS SDK v2的版本号,但代码全是v1的API(DefaultRequest、AWS4Signer、AmazonHttpClient等),v1和v2的API完全不兼容,这是核心问题。必须统一使用v2的规范实现。

  2. 缺失必要请求头
    Lambda Function URL要求请求携带Content-Type: application/json头,你当前代码未设置,会导致请求被拒绝,进而触发错误响应处理时的空指针异常。

  3. 修正后的v2代码示例

import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;

import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

public class LambdaUrlCaller {
    private static final String LAMBDA_URL = "你的Function URL";
    private static final String ACCESS_KEY = "你的访问密钥";
    private static final String SECRET_KEY = "你的秘密密钥";
    private static final Region REGION = Region.of("你的区域");

    public static void main(String[] args) {
        String postJson = "{\"test\": \"data\"}";

        // 构建请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");

        // 构建未签名请求
        SdkHttpFullRequest.Builder requestBuilder = SdkHttpFullRequest.builder()
                .method(SdkHttpMethod.POST)
                .uri(URI.create(LAMBDA_URL))
                .headers(headers)
                .contentStreamProvider(() -> SdkBytes.fromUtf8String(postJson).asInputStream());

        // 签名请求
        Aws4Signer signer = Aws4Signer.create();
        SdkHttpFullRequest signedRequest = signer.sign(
                requestBuilder.build(),
                Aws4Signer.builder()
                        .credentials(AwsBasicCredentials.create(ACCESS_KEY, SECRET_KEY))
                        .region(REGION)
                        .serviceName("lambda")
                        .build()
        );

        // 执行请求并处理响应
        try (UrlConnectionHttpClient client = UrlConnectionHttpClient.create()) {
            software.amazon.awssdk.http.HttpResponse response = client.execute(signedRequest);
            System.out.println("响应状态码: " + response.statusCode());
            
            // 读取响应内容
            InputStream responseStream = response.contentStreamProvider().get();
            // 处理响应流逻辑...
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

额外注意事项

  • 确认Lambda Function URL的认证类型设置为AWS_IAM,否则签名会被忽略或拒绝。
  • 确保IAM用户的权限策略包含lambda:InvokeFunctionUrl,并指定正确的Function ARN。
  • v2 SDK会自动处理Content-Length,无需手动计算,避免编码不一致导致的长度错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:10:57