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

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
}

问题原因及解决方法

  1. 依赖冲突:同时引入Spring官方spring-boot-starter-graphql和第三方graphql-spring-boot-starter,两者的Servlet处理逻辑不兼容,导致异步支持失效。

    • 处理:移除其中一个依赖,优先保留Spring官方的spring-boot-starter-graphql,它对Spring生态的异步支持更适配。
  2. 开启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;
          }
      }
      
  3. 订阅逻辑优化:当前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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:00:11