Spring Cloud Gateway 开发者指南

Writing Custom GatewayFilter Factories

为了编写GatewayFilter,您需要实现GatewayFilterFactory。有一个名为AbstractGatewayFilterFactory的抽象类,您可以扩展它

PreGatewayFilterFactory.java

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

	public PreGatewayFilterFactory() {
		super(Config.class);
	}

	@Override
	public GatewayFilter apply(Config config) {
		// grab configuration from Config object
		return (exchange, chain) -> {
            //If you want to build a "pre" filter you need to manipulate the
            //request before calling chain.filter
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to manipulate the request
            return chain.filter(exchange.mutate().request(request).build());
		};
	}

	public static class Config {
        //Put the configuration properties for your filter here
	}

}

PostGatewayFilterFactory.java

public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

	public PostGatewayFilterFactory() {
		super(Config.class);
	}

	@Override
	public GatewayFilter apply(Config config) {
		// grab configuration from Config object
		return (exchange, chain) -> {
			return chain.filter(exchange).then(Mono.fromRunnable(() -> {
				ServerHttpResponse response = exchange.getResponse();
				//Manipulate the response in some way
			}));
		};
	}

	public static class Config {
        //Put the configuration properties for your filter here
	}

}

Writing Custom Global Filters

要编写自定义全局过滤器,您需要实现GlobalFilter接口。这将过滤器应用于所有请求。分别如何设置全局前置和后置过滤器的示例。

@Bean
public GlobalFilter customGlobalFilter() {
    return (exchange, chain) -> exchange.getPrincipal()
        .map(Principal::getName)
        .defaultIfEmpty("Default User")
        .map(userName -> {
          //adds header to proxied request
          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
          return exchange;
        })
        .flatMap(chain::filter);
}

@Bean
public GlobalFilter customGlobalPostFilter() {
    return (exchange, chain) -> chain.filter(exchange)
        .then(Mono.just(exchange))
        .map(serverWebExchange -> {
          //adds header to response
          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
          return serverWebExchange;
        })
        .then();
}

Building a Simple Gateway Using Spring MVC or Webflux

Spring Cloud Gateway提供了一个名为ProxyExchange的实用程序对象,您可以在常规Spring Web处理程序中将其用作方法参数。它通过镜像HTTP谓词的方法支持基本的下游HTTP交换。使用MVC,它还支持通过forward()方法转发到本地处理程序。要使用ProxyExchange,只需在类路径中包含正确的模块(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的所有功能都可用于Gateway处理程序方法。例如,您可以注入请求标头和查询参数,并且您可以使用映射注释中的声明来约束传入的请求。

有关这些功能的更多详细信息,请参阅Spring MVC中的@RequestMapping文档。

可以使用ProxyExchange上的header()方法将标头添加到下游响应中。

您还可以通过向get()等方法添加映射器来操作响应标头(以及响应中您喜欢的任何其他内容)。映射器是一个Function,它接收传入的ResponseEntity并将其转换为传出的ResponseEntity。为“敏感”标题(默认情况下为“cookie”和“授权”)提供了一流的支持,这些标题不向下游传递,也为“代理”标题(x-forwarded- *)提供。

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/88761181
今日推荐