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

Spring Boot Webflux测试中WebTestClient如何正确解析String[]响应

问题原因

这个问题的根源是WebTestClient的默认编解码器匹配逻辑:

  • 调用expectBodyList(String.class)时,客户端会优先匹配纯字符串解码器,这个解码器不会做JSON结构解析,直接把整个响应体内容(也就是接口返回的完整JSON数组字符串["Fruits","Regional"])作为单个字符串元素存入列表,最终你拿到的就是长度为1、内容是完整JSON串的列表。
  • 你同时引入了Servlet栈的spring-boot-starter-web和响应式栈的spring-boot-starter-webflux,Spring Boot在这种混合栈场景下自动配置的WebTestClient不会自动为String类型目标启用JSON反序列化逻辑。Postman直接调用能看到正常数组是因为Postman会自动对响应做JSON格式化展示,和客户端的解码逻辑无关。
解决方案

两种方案任选即可,优先推荐第一种:

方案1:明确指定泛型类型触发JSON反序列化

不要直接传String.class作为列表元素类型,用ParameterizedTypeReference明确声明目标类型为List<String>,强制WebTestClient调用Jackson JSON解码器解析响应结构。
修改后的测试代码逻辑如下:

import org.springframework.core.ParameterizedTypeReference;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class StackOverFlowControllerTest {

    @Autowired
    WebTestClient webTestClient;

    @Test
    void whenListOfStringsEndpoint_thenExpectListOfStrings(){
        List<String> actual = webTestClient.get()
                .uri("/allBoxes")
                .exchange()
                .expectStatus().is2xxSuccessful()
                .expectBody(new ParameterizedTypeReference<List<String>>() {})
                .returnResult()
                .getResponseBody();

        assertEquals(List.of("Fruits", "Regional"), actual);
    }
}

这种写法会明确告诉WebTestClient需要把响应解析成字符串列表,JSON解码器会自动把数组拆成两个独立的字符串元素,断言就能正常通过。

方案2:自定义WebTestClient编解码器配置

如果你想保留expectBodyList(String.class)的写法,可以手动初始化WebTestClient,调整编解码器的优先级,让JSON解码器优先处理字符串类型响应:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class StackOverFlowControllerTest {

    private WebTestClient webTestClient;

    @Autowired
    void initWebTestClient(ApplicationContext context) {
        this.webTestClient = WebTestClient.bindToApplicationContext(context)
                .configureClient()
                .codecs(config -> config.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                .build();
    }

    // 原有测试方法无需修改
}

这种方式灵活性更高,但类型声明不如方案1清晰,后续维护时容易因为编解码器配置变动出现非预期行为。

补充建议

如果你的项目是纯Spring MVC(Servlet栈)应用,没有实际使用WebFlux的响应式能力,测试Web层更推荐使用MockMvc,可以完全避免两种Web栈混合带来的默认配置差异问题,只需要添加@AutoConfigureMockMvc注解,注入MockMvc实例发起请求即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 09:12:30