SpringBoot3 Webflux整合GraphQL报错:No ContextAccessor for contextType: class reactor.util.context.Context
SpringBoot3 Webflux整合GraphQL报错:No ContextAccessor for contextType: class reactor.util.context.Context
嗨,我之前也踩过Spring Boot 3.1.x版本里Webflux与GraphQL整合的这个坑,刚好能给你一些实用的解决办法!
问题原因
这个报错本质是因为Spring GraphQL在3.1.x版本中,默认提供的上下文访问器(ContextAccessor)并没有适配Reactor的reactor.util.context.Context类型。当你在Webflux的反应式环境中调用GraphQL接口时,框架无法识别并处理这种上下文类型,就会抛出这个异常。
解决方案(无需升级Spring Boot)
既然不能升级版本,我们可以手动注册一个适配Reactor Context的自定义ContextAccessor,再配合拦截器把Reactor上下文传入GraphQL上下文里,具体步骤如下:
1. 自定义Reactor上下文访问器
创建一个实现GraphQlContextAccessor接口的类,专门处理Reactor的Context类型:
import graphql.GraphQlContext; import org.springframework.graphql.context.GraphQlContextAccessor; import reactor.util.context.Context; public class ReactorContextAccessor implements GraphQlContextAccessor { @Override public <T> T getValue(GraphQlContext context, Class<T> contextType) { // 匹配Reactor的Context类型并返回 if (Context.class.isAssignableFrom(contextType)) { return contextType.cast(context.getOrDefault(Context.class, Context.empty())); } return null; } }
2. 注册自定义组件到Spring容器
编写一个配置类,把上面的ContextAccessor和上下文传播拦截器注册为Bean:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.graphql.server.WebGraphQlInterceptor; import org.springframework.graphql.server.WebGraphQlRequest; import reactor.util.context.Context; @Configuration public class GraphQLContextConfig { // 注册自定义的Reactor上下文访问器 @Bean public ReactorContextAccessor reactorContextAccessor() { return new ReactorContextAccessor(); } // 注册拦截器,将Webflux的Reactor上下文传入GraphQL上下文 @Bean public WebGraphQlInterceptor reactorContextPropagationInterceptor() { return (request, chain) -> { return Mono.deferContextual(reactorCtx -> { // 修改GraphQL请求,把Reactor上下文存入GraphQL上下文 WebGraphQlRequest modifiedRequest = request.mutate() .context(graphQlCtx -> graphQlCtx.put(Context.class, reactorCtx)) .build(); return chain.next(modifiedRequest); }); }; } }
3. 在DataFetcher中使用上下文(可选)
配置完成后,你就可以在GraphQL的数据获取器(DataFetcher)中正常获取Reactor上下文了,比如:
@DgsData(parentType = "Query", field = "userInfo") public Mono<UserInfo> getUserInfo(DgsDataFetchingEnvironment env) { // 从GraphQL上下文取出Reactor Context Context reactorContext = env.getGraphQlContext().get(Context.class); // 这里可以根据上下文做权限校验、参数传递等操作 return userService.getUserInfo() .contextWrite(reactorContext); // 传递上下文到后续的反应式链中 }
注意事项
- 如果你的项目中已经存在其他自定义的
GraphQlContextAccessor,请确保它们之间没有类型匹配冲突,优先让ReactorContextAccessor处理Context类型。 - 这个方案完全基于Spring Boot 3.1.5版本的API编写,不需要升级依赖,适合你的场景。
备注:内容来源于stack exchange,提问作者Ladu anand
相关产品推荐
相关产品推荐

