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

Spring Webflux中通过WebFilter实现服务端请求转发到外部应用

Spring Boot Webflux 服务端请求转发实现方案

你需要实现的是服务端反向代理转发,整个转发逻辑在应用内部完成,客户端无感知,可完整保留原始请求的请求头、请求体。

你之前使用的response.getHeaders().setLocation(mutatedURL)属于客户端3xx重定向逻辑:服务端仅返回重定向状态码和目标地址,由客户端主动发起新请求到目标地址,会丢失原始请求的非GET类请求体,且客户端可感知到地址变化,不符合你的需求。


实现步骤(手动WebClient方案,最灵活,支持自定义过滤逻辑)

1. 基础依赖确认

确保项目已引入WebFlux starter,包含所需的WebClient响应式HTTP客户端:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2. 编写全局WebFilter实现转发逻辑

直接实现org.springframework.web.server.WebFilter接口,在过滤器中完成请求拦截、逻辑判断、转发、响应回写的全流程:

import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.core.io.buffer.DataBuffer;
import reactor.core.publisher.Mono;

@Component
public class ForwardFilter implements WebFilter {

    // 初始化WebClient,可根据需求配置连接超时、连接池、SSL校验等参数
    private final WebClient webClient = WebClient.create();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest originalRequest = exchange.getRequest();
        ServerHttpResponse originalResponse = exchange.getResponse();

        // 你的自定义过滤逻辑:判断是否需要转发,不符合则走原有业务流程
        boolean needForward = checkNeedForward(originalRequest);
        if (!needForward) {
            return chain.filter(exchange);
        }

        // 构造目标转发地址,替换为你的外部应用地址+原始请求路径+查询参数
        String targetUrl = "http://你的外部应用地址" + originalRequest.getPath().value() + 
                (originalRequest.getQueryParams().isEmpty() ? "" : "?" + originalRequest.getQueryParams());

        // 转发请求,携带原始请求的方法、头、完整请求体
        return webClient.method(originalRequest.getMethod())
                .uri(targetUrl)
                // 复制原始请求头,可按需过滤不需要传递的头(如Host等)
                .headers(httpHeaders -> {
                    httpHeaders.addAll(originalRequest.getHeaders());
                    httpHeaders.remove("Host"); // 避免目标服务Host校验失败
                })
                .body(BodyInserters.fromDataBuffers(originalRequest.getBody()))
                .exchangeToMono(forwardResponse -> {
                    // 复制外部应用返回的响应头到原始响应
                    originalResponse.getHeaders().putAll(forwardResponse.headers().asHttpHeaders());
                    // 复制外部应用返回的状态码到原始响应
                    originalResponse.setStatusCode(forwardResponse.statusCode());
                    // 把外部应用的响应体写回给原始请求的调用方
                    return originalResponse.writeWith(forwardResponse.bodyToFlux(DataBuffer.class));
                });
    }

    private boolean checkNeedForward(ServerHttpRequest request) {
        // 实现你的自定义判断逻辑,比如按路径、请求头、参数判断是否需要转发
        return request.getPath().value().startsWith("/需要转发的路径前缀/");
    }
}

关键注意事项

  • 该方案基于响应式流实现,可完美处理大文件上传、大响应体等场景,不会出现内存溢出问题
  • 可根据业务需求自定义WebClient的超时、连接池、重试策略等配置,满足不同外部服务的调用要求
  • 如果转发规则比较固定,也可引入Spring Cloud Gateway依赖,通过配置式路由实现转发,无需手动编码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:30:01