Spring MVC返回Flux<String>时中文变为问号的问题求助
解决Spring MVC中Flux返回SSE时中文乱码问题
问题分析
日志打印中文正常,但接口返回data:????,说明内存中的字符串编码是正确的,问题出在响应输出时的编码转换——Spring在将字符串写入响应流时,可能使用了默认的ISO-8859-1编码而非UTF-8,导致中文被错误转码。
可行解决方案
方案1:手动强制设置响应编码
在接口方法中直接设置HttpServletResponse的字符编码和内容类型,覆盖默认配置:
@GetMapping(value = "/chat", produces = "text/event-stream; charset=UTF-8") public Flux<String> chat(@RequestParam String message, @RequestParam(required = false) String tag, HttpServletResponse response) { // 强制设置响应编码 response.setCharacterEncoding("UTF-8"); response.setContentType("text/event-stream; charset=UTF-8"); Flux<String> content = ragService.chat(message, tag) .filter(StringUtils::isNotBlank) .doOnNext(data -> log.info("Sending SSE data: [length={}, content={}]", Objects.requireNonNull(data).length(), data)) .doOnError(e -> log.error("SSE error: {}", e.getMessage())); return content; }
方案2:使用ServerSentEvent封装返回值
改用Flux<ServerSentEvent<String>>作为返回类型,Spring会更规范地处理SSE响应的编码:
@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<String>> chat(@RequestParam String message, @RequestParam(required = false) String tag) { return ragService.chat(message, tag) .filter(StringUtils::isNotBlank) .map(data -> ServerSentEvent.builder(data) .build()) .doOnNext(event -> log.info("Sending SSE data: [content={}]", event.data())) .doOnError(e -> log.error("SSE error: {}", e.getMessage())); }
注:此时无需手动指定charset,Spring会自动根据
TEXT_EVENT_STREAM_VALUE的默认编码(UTF-8)处理。
方案3:全局配置字符串消息编码器
如果多个接口都有类似问题,可以通过配置类全局强制字符串编码器使用UTF-8:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8); // 优先使用自定义的UTF-8编码器 converters.add(0, stringConverter); } }
验证建议
测试时可以用浏览器开发者工具查看响应头的Content-Type是否包含charset=UTF-8,同时检查响应体的编码格式是否为UTF-8。
内容的提问来源于stack exchange,提问作者loveTang
相关产品推荐
相关产品推荐

