部署在AWS Lambda的Spring Boot 3 GraphQL API遭遇HttpMessageNotReadableException
问题:Spring Boot GraphQL部署到AWS Lambda后出现JSON解析错误
场景
使用spring-boot-starter-graphql和aws-serverless-java-container-springboot3将简单GraphQL API部署到AWS Lambda,前端搭配AWS HTTP API Gateway。本地Tomcat环境下请求可正常处理,但部署到Lambda后触发org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: No content to map due to end-of-input异常,排查三天未解决。
版本信息
- Serverless Java Container版本:
2.0.0-M1 - 实现框架:
Spring Boot 3 - Spring Boot版本:
3.1.0 - 前端服务:
HTTP API - 部署方式:
Console
预期行为
调用HTTP API Gateway的/graphql接口应返回200响应,示例curl命令:
curl 'https://[APIGATEWAY_URL]/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'Origin: altair://-' --data-binary '{"query":"query example{\n exampleQuery(input: { id: 1 }) {\n ok\n }\n}\n","variables":{}}' --compressed
实际行为
触发JSON解析错误,具体日志如下:
复现步骤
可通过仅包含5个类的项目复现该问题
完整日志输出
START RequestId: 5beefda9-8340-4539-a1b1-c1e154571024 Version: $LATEST -- 2023-05-31T07:18:56.999Z TRACE 8 --- [ main] o.s.b.w.s.f.OrderedRequestContextFilter : 绑定请求上下文到线程: com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequest@450794b4 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.web.servlet.DispatcherServlet : POST "/graphql", 参数={}, 请求头={已隐藏},进入DispatcherServlet 'dispatcherServlet' 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : 请求方法"[GET]"与"POST"不匹配 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : 请求方法"[POST]"与"POST"匹配 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : 路径"/graphql"与"/graphql"匹配 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : Content-Type "[application/json]"与"application/json;charset=UTF-8"匹配 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : Accept "[application/graphql-response+json, application/json, application/graphql+json]"与"[application/json]"匹配 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.servlet.function.RouterFunctions : 断言"((POST && /graphql) && (Content-Type: application/json && Accept: [application/graphql-response+json, application/json, application/graphql+json]))"匹配"HTTP POST /graphql" 2023-05-31T07:18:57.000Z TRACE 8 --- [ main] o.s.w.s.f.support.RouterFunctionMapping : 映射到org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration$Lambda$909/0x0000000801c42aa0@332a7fce 2023-05-31T07:18:57.001Z DEBUG 8 --- [ main] o.s.g.server.webmvc.GraphQlHttpHandler : 执行查询: document='query example{ exampleQuery(input: { id: 1 }) { ok } } ', operationName='example', id=a1e5941b-7608-2e7e-389f-de1c93d105df, 语言=ko 2023-05-31T07:18:57.003Z TRACE 8 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : 返回单例bean 'exampleController'的缓存实例 2023-05-31T07:18:57.003Z TRACE 8 --- [ main] o.s.graphql.data.method.HandlerMethod : 参数: [TestInput(id=1)] 2023-05-31T07:18:57.003Z DEBUG 8 --- [ main] o.s.g.server.webmvc.GraphQlHttpHandler : 查询执行完成 2023-05-31T07:18:57.004Z DEBUG 8 --- [ main] o.s.w.c.request.async.WebAsyncManager : 启动异步请求 2023-05-31T07:18:57.004Z DEBUG 8 --- [ main] o.s.w.c.request.async.WebAsyncManager : 设置异步结果,分发到/graphql 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.web.servlet.DispatcherServlet : "ASYNC"分发POST "/graphql", 参数={}, 请求头={已隐藏},进入DispatcherServlet 'dispatcherServlet' 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : 请求方法"[GET]"与"POST"不匹配 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : 请求方法"[POST]"与"POST"匹配 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : 路径"/graphql"与"/graphql"匹配 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : Content-Type "[application/json]"与"application/json;charset=UTF-8"匹配 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.s.function.RequestPredicates : Accept "[application/graphql-response+json, application/json, application/graphql+json]"与"[application/json]"匹配 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.servlet.function.RouterFunctions : 断言"((POST && /graphql) && (Content-Type: application/json && Accept: [application/graphql-response+json, application/json, application/graphql+json]))"匹配"HTTP POST /graphql" 2023-05-31T07:18:57.004Z TRACE 8 --- [ main] o.s.w.s.f.support.RouterFunctionMapping : 映射到org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration$Lambda$909/0x0000000801c42aa0@332a7fce 2023-05-31T07:18:57.005Z WARN 8 --- [ main] .w.s.m.s.DefaultHandlerExceptionResolver : 解析异常: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: No content to map due to end-of-input 2023-05-31T07:18:57.005Z TRACE 8 --- [ main] o.s.web.servlet.DispatcherServlet : 无视图渲染,返回null ModelAndView 2023-05-31T07:18:57.005Z DEBUG 8 --- [ main] o.s.web.servlet.DispatcherServlet : 退出"ERROR"分发,状态码400,请求头={} 2023-05-31T07:18:57.005Z TRACE 8 --- [ main] o.s.web.servlet.DispatcherServlet : 无视图渲染,返回null ModelAndView 2023-05-31T07:18:57.005Z DEBUG 8 --- [ main] o.s.web.servlet.DispatcherServlet : 退出"ERROR"分发,状态码400,请求头={} 2023-05-31T07:18:57.005Z TRACE 8 --- [ main] o.s.b.w.s.f.OrderedRequestContextFilter : 清除线程绑定的请求上下文: com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequest@450794b4 2023-05-31T07:18:57.005Z INFO 8 --- [ main] c.a.s.p.internal.LambdaContainerHandler : 222.237.84.246 null- null [31/05/2023:07:18:56Z] "POST /graphql HTTP/1.1" 400 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) AltairGraphQLClient/5.0.20 Chrome/102.0.5005.167 Electron/19.0.10 Safari/537.36" combined END RequestId: 5beefda9-8340-4539-a1b1-c1e154571024 REPORT RequestId: 5beefda9-8340-4539-a1b1-c1e154571024 Duration: 9.80 ms Billed Duration: 10 ms Memory Size: 1024 MB Max Memory Used: 192 MB
内容的提问来源于stack exchange,提问作者kibeom lee
相关产品推荐
相关产品推荐

