Unable to execute HTTP request (DynamoDB, Java SDK)

TL;DR — Java SDK 从未收到 HTTP 响应:到 DynamoDB 端点的 TCP 连接失败了。对着 localhost:8000,这意味着 DynamoDB Local 未运行(或在另一个端口上)——而在 Docker/SAM 容器内部,localhost 是_那个容器_,而不是你的机器,因此模拟器在那个地址上不可达。启动模拟器、修正端点,并从容器中使用一个主机可达的地址。

含义

com.amazonaws.SdkClientException: Unable to execute HTTP request:
Connect to localhost:8000 [localhost/127.0.0.1] failed: Connection refused

SdkClientException(v1:AmazonClientException)是 SDK 的客户端失败封装——请求在 DynamoDB 看到它之前就夭折了。嵌套的原因会告诉你是哪一步网络失败了:Connection refused(没有东西在监听)、connect timed out(无路由/防火墙)或 UnknownHostException(主机名无法解析,常常是拼错的区域或端点)。它是 botocore 的 Could not connect to the endpoint URL 的 Java 等价物。

为什么会发生

  • DynamoDB Local 未运行——它从未启动、在启动时崩溃(原生库端口冲突),或随你上一个终端一起退出了。
  • 端口或协议错误——Local 默认在 8000 上使用纯 httphttps://localhost:8000 的端点或错误的端口会拒绝连接。
  • 容器内部的 localhost——运行在 Docker/SAM(sam local invoke)中的代码拨的是它_自己_的环回地址。你主机上(或在一个兄弟容器中)的模拟器并不在那里。
  • 对着真实 AWS:没有网络路径——SDK 的 HTTP 客户端上没有配置公司代理、VPC 没有到 DynamoDB 的路由/端点,或者拼错的区域产生了一个不存在的主机名。

如何修复

  1. 确认你拨号的地方有东西在监听:

    curl http://localhost:8000    # DynamoDB Local answers 400 with an AmazonDynamoDBv2 body

    如果失败,就启动模拟器(java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jardocker run -p 8000:8000 amazon/dynamodb-local)。

  2. 把客户端指向正确的端点(v2 SDK):

    DynamoDbClient client = DynamoDbClient.builder()
        .endpointOverride(URI.create("http://localhost:8000"))
        .region(Region.US_EAST_1)
        .build();
  3. 从容器中,不要拨 localhost——使用 host.docker.internal:8000(Docker Desktop)、compose 服务名(http://dynamodb:8000),或把两个容器都接到同一个 Docker 网络。对于 sam local,传入一个与模拟器容器共享的 --docker-network

  4. 对着真实 AWS,核实区域主机名正确,并在你的网络需要时配置 SDK 的代理设置;从私有子网中,添加一个 DynamoDB 网关 VPC 端点或 NAT 路由。

一旦端点有响应,就端到端地核实数据流通——DynoTable 桌面应用既连接 DynamoDB Local 也连接真实 AWS,因此你能看到你的 Java 代码正在(或没有)访问哪些表。在构建请求本身?DynamoDB Expression Builder 会生成正确的键条件和带类型的值。

相关错误

References

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

DynoTable 是面向 DynamoDB 的快速桌面客户端 —— 浏览表、运行 SQL 风格的查询,并在本地编辑项。