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

如何在Spring Boot中代理转发端点请求?开发环境路径转发方案

实现Spring Boot开发环境下的路径代理(类似webpack devServer.proxy)

问题分析

你之前的代码使用redirect会触发浏览器重定向,直接请求目标端口18896,这和代理需求不符——代理需要后端内部转发请求,前端完全感知不到目标地址。同时代码没有保留请求路径的后缀部分(比如/something/1中的1),导致转发路径不完整。

解决方案

以下两种方案都能实现类似webpack devServer.proxy的代理效果,且仅在开发环境生效,无需修改前端代码。

方案一:使用Spring Cloud Gateway(推荐,配置驱动)

这种方式无需编写Java代码,仅通过配置即可实现代理,适合大多数场景。

  1. 引入依赖
    在pom.xml中添加Spring Cloud Gateway依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 开发环境配置
    在application-dev.yml中添加路由配置(仅在开发环境加载):
spring:
  cloud:
    gateway:
      routes:
        - id: something-service-proxy
          uri: http://localhost:18896  # 目标服务地址
          predicates:
            - Path=/something/**  # 匹配需要代理的路径

当前端请求http://localhost:19988/something/1时,Gateway会自动将请求转发到http://localhost:18896/something/1,并将响应原封不动返回给前端。

方案二:使用Controller + WebClient(无额外依赖,代码实现)

如果不想引入Spring Cloud Gateway,可以通过编写Controller结合WebClient实现转发,确保仅在开发环境生效。

  1. 配置目标地址
    在application-dev.yml中添加代理目标地址:
proxy:
  target-url: http://localhost:18896
  1. 编写代理Controller
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;

@RestController
@RequestMapping("/something")
@Profile("dev")  # 仅在开发环境启用该Controller
public class SomethingProxyController {

    private final WebClient webClient;
    private final String targetBaseUrl;

    public SomethingProxyController(WebClient.Builder webClientBuilder,
                                    @Value("${proxy.target-url}") String targetBaseUrl) {
        this.webClient = webClientBuilder.baseUrl(targetBaseUrl).build();
        this.targetBaseUrl = targetBaseUrl;
    }

    @RequestMapping(value = "/**", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
    public ResponseEntity<?> proxyRequest(@PathVariable("**") String pathSegment,
                                          @RequestHeader HttpHeaders headers,
                                          @RequestBody(required = false) String requestBody,
                                          HttpMethod requestMethod) {
        // 移除可能导致转发冲突的Host头
        headers.remove(HttpHeaders.HOST);

        return webClient.method(requestMethod)
                .uri("/something/{path}", pathSegment)
                .headers(httpHeaders -> httpHeaders.addAll(headers))
                .bodyValue(requestBody)
                .retrieve()
                .toEntity(String.class)
                .block();
    }
}
  • @Profile("dev")确保该Controller仅在开发环境生效,生产环境不会加载。
  • @PathVariable("**")捕获/something之后的所有路径部分(比如1、detail/2等)。
  • WebClient负责将请求转发到目标服务,保留原请求的方法、头信息和请求体,并将目标服务的响应返回给前端。

注意事项

  • 生产环境无需任何配置,因为两服务共用同一URL,请求会直接到达对应服务。
  • 如果项目使用同步编程模型,可以用RestTemplate替代WebClient,核心逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:05:17