Spring Boot 2.6.6返回SSE时遇Response类转换器缺失问题求助
问题解决方法
问题根源
错误No converter for [class misc.contract.response.Response] with preset Content-Type 'text/event-stream;charset=UTF-8'的核心原因是:
- 服务端存在全局响应包装逻辑(比如
ResponseBodyAdvice实现),将所有接口的返回值统一包装成了Response对象,包括SSE接口。 - Spring对SSE的处理要求直接返回
SseEmitter实例,而包装后的Response<SseEmitter>无法被text/event-stream类型的消息转换器处理。
具体解决方案
1. 排除SSE接口的全局响应包装
如果项目中使用了ResponseBodyAdvice统一包装响应,修改该类,跳过对SSE接口的包装:
@ControllerAdvice public class GlobalResponseWrapper implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { // 排除返回类型为SseEmitter的方法,不进行包装 return !returnType.getParameterType().equals(SseEmitter.class); } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 原有包装逻辑仅对非SSE请求生效 if (body instanceof Response) { return body; } return new Response<>(body); } }
2. 确保SSE接口实现直接返回SseEmitter
检查IAiSseChatController的实现类,确保askStream方法直接返回SseEmitter实例,而非Response<SseEmitter>:
@RestController public class AiSseChatController implements IAiSseChatController { @Override public SseEmitter askStream(String question) { SseEmitter emitter = new SseEmitter(); // 异步处理逻辑,向emitter发送事件 new Thread(() -> { try { // 模拟发送SSE事件 emitter.send("Hello, SSE!"); emitter.complete(); } catch (IOException e) { emitter.completeWithError(e); } }).start(); return emitter; } }
3. 验证Feign接口与实现的一致性
确认Feign接口IAiSseChatController定义的返回类型是SseEmitter,实现类的返回类型与之完全匹配,避免类型不匹配触发不必要的包装逻辑。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

