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

如何在Spring Cloud Gateway过滤器中将WebClient响应转为ServerHttpResponse?

Spring Cloud Gateway过滤器中用WebClient转发响应的实现方案

核心实现思路

当请求头包含Test时,通过WebClient调用目标服务,将目标服务的响应(状态码、响应头、响应体)直接作为网关的响应返回,不再继续执行后续过滤器链。

完整代码实现

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomForwardFilter implements GatewayFilter {

    private final WebClient webClient;

    // 推荐通过构造注入WebClient,避免每次创建新实例
    public CustomForwardFilter(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.build();
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (exchange.getRequest().getHeaders().containsKey("Test")) {
            ServerHttpResponse response = exchange.getResponse();
            String targetUrl = "http://localhost:8080/test";

            return webClient.get()
                    .uri(targetUrl)
                    .exchangeToMono(clientResponse -> {
                        // 复制目标服务的响应状态码
                        response.setStatusCode(clientResponse.statusCode());
                        // 复制目标服务的响应头(排除Transfer-Encoding等网关会处理的头)
                        HttpHeaders targetHeaders = clientResponse.headers().asHttpHeaders();
                        response.getHeaders().putAll(targetHeaders);
                        // 写入响应体到网关响应
                        return response.writeWith(clientResponse.bodyToFlux(byte[].class));
                    });
        }
        // 不满足条件时继续执行过滤器链
        return chain.filter(exchange);
    }
}

关键细节说明

  • WebClient实例管理:不要每次调用都用WebClient.create()创建新实例,推荐通过WebClient.Builder注入,实现复用和统一配置。
  • 响应头处理:复制目标服务的响应头时,网关会自动处理Transfer-Encoding、Content-Length等头,无需手动干预。
  • 响应体写入:使用bodyToFlux(byte[].class)将目标服务的响应体转为Flux,再通过response.writeWith()写入到网关响应中,保证响应体完整传输。
  • 异常处理(可选):如果需要处理目标服务调用失败的情况,可以添加onErrorResume逻辑,比如返回自定义错误响应:
    .onErrorResume(e -> {
        response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
        response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
        String errorMsg = "调用目标服务失败: " + e.getMessage();
        return response.writeWith(Mono.just(response.bufferFactory().wrap(errorMsg.getBytes())));
    })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:47:17