异步请求因RequestFacade被回收失败的排查与解决求助
解决异步Vaadin视图调用OAuth2保护GraphQL接口时的请求回收异常
问题场景
使用Vaadin异步视图,通过NewsService调用GraphQlService,借助Spring HttpGraphQlClient发起OAuth2保护的GraphQL请求。本地运行完全正常,但测试服务器上约50%概率抛出异常:
The request object has been recycled and is no longer associated with this facade
问题根源
该异常是由于HTTP请求上下文被容器回收后,代码仍尝试访问已销毁的Request对象导致的。在Vaadin异步加载场景中,前端HTTP请求可能已完成并被容器回收,但后台的GraphQL请求(及关联的OAuth2授权流程)仍在执行,此时若OAuth2流程尝试从已过期的Request中读取属性(如scope参数),就会触发该异常。
已尝试的方案对比
- 依赖HTTP请求的
GraphQlService实现:符合生产环境需求,但存在随机异常; - 不依赖HTTP请求的实现:可避免异常,但无法自动续期OAuth2访问令牌。
验证有效的解决方案
替换默认的DefaultOAuth2AuthorizedClientManager.DefaultContextAttributesMapper为空实现,阻止OAuth2授权流程从已过期的请求中读取参数:
@Bean public OAuth2AuthorizedClientManager authorizedClientManager( ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) { DefaultOAuth2AuthorizedClientManager manager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository); // 设置为空实现,避免访问已回收的请求对象 manager.setContextAttributesMapper((context) -> Collections.emptyMap()); return manager; }
该方案通过切断OAuth2流程与HTTP请求上下文的关联,避免了对已回收Request对象的访问,目前测试未再出现异常。
额外建议
如果业务需要从请求上下文获取OAuth2授权参数(如动态scope),可以将所需参数提前从请求中提取并保存到独立的上下文(如Vaadin的UI上下文或自定义的异步任务上下文),再传递给OAuth2授权流程,避免直接访问已过期的Request对象。
内容的提问来源于stack exchange,提问作者Sebastian Lütge
相关产品推荐
相关产品推荐

