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

WebClient如何使用ResponseEntity<Mono<String>>发起GET调用?

WebClient 实现GET请求提前获取响应头并行处理的方案

根据Spring WebFlux的官方特性说明:

使用ResponseEntity<Mono<T>>或ResponseEntity<Flux<T>>结构处理响应时,客户端/服务端会在收到响应头、响应状态码后立刻触发对应逻辑,不需要等待整个响应体传输、解析完成;单值响应选择Mono作为响应体包装类型,多值/流式响应选择Flux即可。

针对「第一时间获取响应头,等待响应体过程中并行执行其他逻辑」的GET调用场景,具体实现方式如下:

核心实现逻辑

  • 发起请求时不要直接将响应映射为目标实体类,先获取原生响应的包装结构,确保响应头返回后立刻进入处理分支
  • 拿到响应头后,将无需依赖响应体的业务逻辑包装为异步任务,和响应体接收解析流程并行执行
  • 阻塞型的并行处理逻辑必须指定独立调度线程池,避免阻塞WebFlux核心IO线程

完整代码示例

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import lombok.extern.slf4j.Slf4j;
import lombok.Data;

@Slf4j
public class HeaderFirstGetClient {
    // 实际项目中可将WebClient注册为全局Bean统一配置超时、拦截器等参数
    private static final WebClient WEB_CLIENT = WebClient.builder()
            .baseUrl("http://target-service-domain")
            .build();

    /**
     * 带响应头提前处理的GET调用
     * @return 解析完成的响应体实体
     */
    public Mono<ResponseDto> getWithParallelHeaderProcess() {
        return WEB_CLIENT.get()
                .uri("/api/target-endpoint")
                // 关键:exchangeToMono会在收到响应头后立刻触发回调,无需等待响应体
                .exchangeToMono(clientResponse -> {
                    // 此处已可同步读取响应状态、所有响应头
                    HttpStatus status = clientResponse.statusCode();
                    HttpHeaders headers = clientResponse.headers().asHttpHeaders();
                    String traceId = headers.getFirst("X-Trace-Id");
                    long contentLen = headers.getContentLength();

                    // 包装不依赖响应体的并行处理逻辑
                    Mono<Void> parallelTask = Mono.fromRunnable(() -> {
                        // 此处写自定义并行逻辑:比如日志埋点、上下文初始化、异步通知等
                        log.info("提前获取响应头完成,traceId:{}, 响应状态:{}", traceId, status.value());
                        // 阻塞操作必须放在boundedElastic调度器执行,避免卡IO线程
                        try {
                            Thread.sleep(150);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                        log.info("响应头相关并行处理执行完成");
                    }).subscribeOn(Schedulers.boundedElastic())
                      .doOnError(e -> log.error("并行处理逻辑执行失败", e)); // 单独处理并行任务异常,避免影响主流程

                    // 异步接收解析响应体
                    Mono<ResponseDto> bodyMono = clientResponse.bodyToMono(ResponseDto.class);

                    // 方案1:等待并行任务和响应体都完成后返回结果
                    return parallelTask.then(bodyMono);

                    // 方案2:不需要等并行任务完成、直接返回响应体(放开下方注释即可)
                    // parallelTask.subscribe();
                    // return bodyMono;
                });
    }

    // 自定义响应体DTO
    @Data
    public static class ResponseDto {
        private Long id;
        private String content;
    }
}

注意事项

  • 如果调用的接口返回数组、SSE流式数据,把bodyToMono替换为bodyToFlux即可,响应头提前读取、并行处理的逻辑完全不变
  • 若选择不等待并行任务直接返回响应体,必须给并行任务单独配置异常处理逻辑,避免异常静默丢失
  • 不要在exchangeToMono的回调主线程里直接写阻塞逻辑,所有阻塞操作必须指定对应调度器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:42:22