You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux返回Flux<String>未生成JSON数组而是拼接字符串的问题

嘿,作为Spring WebFlux新手碰到这个问题太正常了!我来给你理清楚为什么会这样,以及怎么直接返回字符串数组:

首先先把你的代码整理一下,方便看清楚问题:

class Wrapper(val data: String)

@RestController
class Test() {
    @RequestMapping("/wrapped") // 返回有效JSON数组: [{"data":"Hello"},{"data":"World"}]
    fun b() = Flux.just(Wrapper("Hello"), Wrapper("World"))

    @RequestMapping("/raw") // 返回无效结果:HelloWorld
    fun a() = Flux.just("Hello", "World")
}

问题到底出在哪?

当你返回Flux<String>时,Spring WebFlux的默认行为是把它当作文本流来处理——每个字符串元素会被直接输出到响应体里,没有任何JSON序列化的包裹逻辑,所以最终就变成了HelloWorld这种拼接后的纯文本。

而返回Flux<Wrapper>时,因为Wrapper是自定义对象,Spring会自动启用JSON编码器,把每个对象序列化为JSON对象,再组合成数组输出,所以得到的是正确的JSON格式。

至于你说Array<String>能正常工作,是因为Array本身是一个完整的集合对象,Spring会把它当作单个JSON数组来序列化,而不是像Flux<String>那样流式输出每个元素。

直接返回字符串数组的解决方案

这里给你几种实用的方式,按需选择:

方式1:把Flux转为Mono<List>并指定媒体类型

这是最简洁的方案——把流式的Flux收集成一个List,返回Mono<List<String>>,同时明确告诉Spring要返回JSON格式:

import org.springframework.http.MediaType

@RestController
class Test() {
    @RequestMapping("/wrapped")
    fun b() = Flux.just(Wrapper("Hello"), Wrapper("World"))

    @RequestMapping("/raw", produces = [MediaType.APPLICATION_JSON_VALUE])
    fun a(): Mono<List<String>> = Flux.just("Hello", "World").collectList()
}

方式2:用ServerResponse手动构建响应

如果需要更灵活的响应控制(比如自定义状态码、响应头),可以用ServerResponse来明确构建JSON数组响应:

import org.springframework.web.reactive.function.server.ServerResponse
import org.springframework.http.MediaType

@RestController
class Test() {
    @RequestMapping("/wrapped")
    fun b() = Flux.just(Wrapper("Hello"), Wrapper("World"))

    @GetMapping("/raw")
    fun a(): ServerResponse {
        val stringFlux = Flux.just("Hello", "World")
        return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(stringFlux.collectList(), List::class.java)
    }
}

方式3:全局配置编码器(谨慎使用)

如果你希望所有返回Flux<String>的端点都默认返回JSON数组,可以全局修改WebFlux的编码器配置,但这种方式会影响所有端点,所以只在全局需要这个行为时使用:

import org.springframework.context.annotation.Configuration
import org.springframework.http.codec.ServerCodecConfigurer
import org.springframework.web.reactive.config.WebFluxConfigurer

@Configuration
class WebFluxGlobalConfig : WebFluxConfigurer {
    override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
        val jsonEncoder = configurer.defaultCodecs().jackson2JsonEncoder()
        // 让JSON编码器处理String类型的流
        configurer.defaultCodecs().jackson2JsonEncoder(jsonEncoder)
    }
}

验证效果

修改后访问/raw端点,你就能得到预期的JSON数组响应了:

["Hello","World"]

内容的提问来源于stack exchange,提问作者Artem Yarulin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:21:14