Webflux与Flux<String>处理响应时的空格丢失问题排查
解决Flux响应丢失空格的问题
问题分析
调用返回TEXT_EVENT_STREAM类型的Flux接口时,拼接后的输出丢失所有空格,核心原因可能是客户端对SSE事件的解析逻辑未正确保留空格,或服务端返回的事件格式存在特殊处理。
排查与解决步骤
1. 确认服务端原始响应是否包含空格
先通过curl或Postman直接调用接口,查看原始SSE响应内容,验证每个data字段是否包含预期的空格:
curl -X POST \ -H "Content-Type: application/json" \ -d '{"你的请求体内容"}' \ "你的baseUrl/你的uri?temperature=0.3"
如果原始响应就没有空格,需联系服务端排查;若原始响应有空格,继续客户端排查。
2. 改用SseEvent解析完整事件内容
WebClient默认的bodyToFlux<String>可能无法正确处理SSE事件中的空格(比如空格作为单独事件返回时被过滤),改用SseEvent类型解析可确保完整获取每个事件的data字段:
Flux<SseEvent> eventStream = webClientBuilder .clientConnector(new ReactorClientHttpConnector(httpClient)) .baseUrl(baseUrl) .build() .post() .uri(uriBuilder -> uriBuilder.path(uri).queryParam("temperature", "0.3").build(llmType)) .accept(MediaType.TEXT_EVENT_STREAM) .headers(httpHeaders -> httpHeaders.addAll(headers)) .bodyValue(body) .retrieve() .bodyToFlux(SseEvent.class); List<String> resultList = eventStream .map(SseEvent::data) .doOnNext(event -> { log.info("事件内容: '{}' 长度: {}", event, event.length()); }) .collectList() .block(); log.info(String.join("", resultList));
3. 配置StringDecoder禁用自动修剪
如果WebClient的字符串解码器默认修剪了空白字符,可自定义解码器配置,保留所有原始字符:
WebClient webClient = webClientBuilder .clientConnector(new ReactorClientHttpConnector(httpClient)) .baseUrl(baseUrl) .codecs(configurer -> { // 禁用字符串解码器的末尾换行修剪,保留原始空格 configurer.defaultCodecs().stringDecoder( new StringDecoder(MediaType.ALL, StandardCharsets.UTF_8, false) ); }) .build();
4. 检查是否存在URL转义情况
若服务端返回的空格被转义为%20,需在客户端对事件内容进行URL解码:
import java.net.URLDecoder; import java.nio.charset.StandardCharsets; // ... List<String> resultList = eventStream .map(event -> URLDecoder.decode(event, StandardCharsets.UTF_8)) .doOnNext(event -> { log.info("事件内容: '{}' 长度: {}", event, event.length()); }) .collectList() .block();
内容的提问来源于stack exchange,提问作者Marcello Pucci
相关产品推荐
相关产品推荐

