Spring Boot GraphQL订阅报错:当前链过滤器/Servlet不支持异步操作
Spring Boot GraphQL订阅功能异步操作异常解决
访问端点时触发如下异常:
java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations. ...
应用相关组件说明
pom.xml依赖配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-graphql</artifactId> </dependency> <dependency> <groupId>com.graphql-java-kickstart</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>15.1.0</version> </dependency>
GraphQL Resolver代码
@Component public class GraphQLResolver implements GraphQLQueryResolver,GraphQLSubscriptionResolver { public Publisher<Comment> allComments() { List<Comment> comments = Arrays.asList(restTemplate().getForObject(apiUrl, Comment[].class)); return Flux.fromIterable(comments); } }
GraphQL Schema定义
schema { subscription: Subscription } type Subscription { allComments: Comment } type Comment { postId: String id: String name: String email: String body: String }
问题原因及解决方法
依赖冲突:同时引入Spring官方
spring-boot-starter-graphql和第三方graphql-spring-boot-starter,两者的Servlet处理逻辑不兼容,导致异步支持失效。- 处理:移除其中一个依赖,优先保留Spring官方的
spring-boot-starter-graphql,它对Spring生态的异步支持更适配。
- 处理:移除其中一个依赖,优先保留Spring官方的
开启Servlet异步支持:如果必须保留两个依赖,需手动开启Servlet异步支持:
- 在
application.properties中添加配置:spring.graphql.servlet.async-supported=true - 或者自定义Servlet注册Bean:
@Configuration public class GraphQLServletConfig { @Bean public ServletRegistrationBean<GraphQLServlet> graphQLServletRegistrationBean(GraphQLServlet graphQLServlet) { ServletRegistrationBean<GraphQLServlet> registrationBean = new ServletRegistrationBean<>(graphQLServlet, "/graphql"); registrationBean.setAsyncSupported(true); return registrationBean; } }
- 在
订阅逻辑优化:当前Resolver返回的是静态列表转换的Flux,不符合订阅实时推送的设计初衷。如果要实现真正的订阅功能,应该使用事件驱动的Publisher,比如通过
Flux.create创建可推送的流:private final Sinks.Many<Comment> commentSink = Sinks.many().multicast().onBackpressureBuffer(); public Publisher<Comment> allComments() { // 这里可以添加事件监听逻辑,比如当有新Comment时调用commentSink.tryEmitNext(comment) return commentSink.asFlux(); }
内容的提问来源于stack exchange,提问作者Ajit Barik
相关产品推荐
相关产品推荐

