使用 Spring MVC 或 Webflux 的代理交换网关
以下描述了一种替代风格的网关。接下来的内容不适用于 Spring Cloud Gateway Server 文档中的任何部分。 |
如何引入 Spring Cloud Gateway Proxy Exchange
要在项目中引入 Spring Cloud Gateway Proxy Exchange,对于 MVC 代理交换,请使用 group ID 为 org.springframework.cloud
、artifact ID 为 spring-cloud-gateway-mvc
的依赖。对于 WebFlux 代理交换,请使用 group ID 为 org.springframework.cloud
、artifact ID 为 spring-cloud-gateway-webflux
的依赖。
有关使用当前 Spring Cloud Release Train 设置构建系统的详细信息,请参阅 Spring Cloud 项目页面。
使用 Proxy Exchange
Spring Cloud Gateway 提供了一个名为 ProxyExchange
的工具对象。您可以在常规 Spring web 处理器中将其用作方法参数。它通过镜像 HTTP 动词的方法支持基本的下游 HTTP 交换。对于 MVC,它还通过 forward()
方法支持转发到本地处理器。要使用 ProxyExchange
,请在您的 classpath 中包含正确的模块(spring-cloud-gateway-mvc
或 spring-cloud-gateway-webflux
)。
以下 MVC 示例将发往 /test
的请求代理到下游的远程服务器
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
以下示例使用 Webflux 实现相同的功能
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
ProxyExchange
上的便利方法使处理器方法能够发现和增强传入请求的 URI 路径。例如,您可能需要提取路径的尾部元素以便向下游传递
@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
Spring MVC 和 Webflux 的所有功能都可供网关处理器方法使用。因此,您可以注入请求头和查询参数等,并且可以通过映射注解中的声明来限制传入请求。有关这些功能的更多详细信息,请参阅 Spring MVC 中关于 @RequestMapping
的文档。
您可以使用 ProxyExchange
上的 header()
方法向下游响应添加头。
您还可以通过向 get()
方法(以及其他方法)添加映射器来操作响应头(以及响应中您喜欢的任何其他内容)。映射器是一个 Function
,它接收传入的 ResponseEntity
并将其转换为传出的响应。
对“敏感”头(默认为 cookie
和 authorization
)和“跳过”头(默认为 content-length
和 host
)提供了一流的支持,这些头不会向下游传递;对于“代理”头(x-forwarded-*
)也提供了支持。“跳过”头的理念是,当它们被复制到下游请求时可能会导致问题。例如:由于 ProxyExchange
调用下游端点的方式,内容的长度可能已经改变,甚至可能使用 Transfer-Encoding: chunked
而不是 Content-Length
头。