Spring Cloud Gateway使用说明(8)-- 开发指导

16. 问题定位

本节覆盖Spring Cloud Gateway开发过程中可能会遇到的问题。

16.1. 日志级别

把下面的包日志级别设置为DEBUG或TARCE可能会看到更多的参数信息:

  • org.springframework.cloud.gateway
  • org.springframework.http.server.reactive
  • org.springframework.web.reactive
  • org.springframework.boot.autoconfigure.web
  • reactor.netty
  • redisratelimiter

16.2. 监听请求

Reactor Netty 的 HttpClient 和 HttpServer 可以开启监听功能。结合设置包reactor.netty 的日志级别设置到debug或trace,会打印出请求的header和body信息。要启动监听功能,设置 spring.cloud.gateway.httpserver.wiretap=true 或 spring.cloud.gateway.httpclient.wiretap=true 开启httpServer或HttpClient 的监听。

17 自定义组件

下面有一些编写网关自定义组件的基本指导。

17.1. 编写自定义路由断言

编写路由断言需要实现接口RoutePredicateFactory。那里有一个抽象类AbstractRoutePredicateFactory可以继承。
MyRoutePredicateFactory.java

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {

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

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // grab configuration from Config object
        return exchange -> {
            //grab the request
            ServerHttpRequest request = exchange.getRequest();
            //take information from the request to see if it
            //matches configuration.
            return matches(config, request);
        };
    }

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

}

17.2. 自定义GatewayFilter

编写GatewayFilter,必须实现接口GatewayFilterFactory。那里有一个抽象类AbstractGatewayFilterFactory可以继承。

Example 74. 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(builder.build()).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
    }

}

17.2.1. 自定义过滤器命名和配置

自定义过滤器的类名应该以GatewayFilterFactory结尾。
比如,在配置文件中引用一个名叫Something的过滤器,该过滤器的类名必须为SomethingGatewayFilterFactory。

注意
网关过滤器的名字可以不以GatewayFilterFactory结尾,比如class AnotherThing。这个过滤器也可以通过AnotherThing在配置文件中引用。但是那不是一个支持的命名约定,在未来的版本中会被移除。请更新过滤器名字以符合约定。

17.3. 自定义全局过滤器

自定义全局过滤器,必须实现GlobalFilter接口。过滤器会应用到所有的请求中。
下面是设置pre和post过滤器的例子:

@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();
}

18. 通过Spring MVC或Webflux实现网关

注意
下文描述一个可选的方式实现网关。前面的文档不适用于下面。

Spring Cloud Gateway 提供一个叫ProxyExchange的工具类。你可以在常规的Spring web handler的方法参数中使用。它支持基本的http请求。通过MVC,也支持通过forward()方法转发到本地的handler。需要添加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特性都可以在网关的handler方法中使用。因此,你可以往请求中注入请求参数和header;也可以在Mapping注解中约束进入的请求。具体请看Spring MVC的@RequestMapping文档。

通过ProxyExchange的header()方法,你可以添加header到响应中。

你也可以给get()方法(或者其它方法)添加一个mapper,以修改响应的header(或响应中的其它东西)。mapper是获得的ResponseEntity中的方法,转化为返回的响应。

优先支持的是提供敏感的header(默认是cookie和authorization),那是不会传递到下游的。也可以添加代理(x-forwarded-*) header

Spring Cloud Gateway 2.2.3 官方使用说明(1)–路由
Spring Cloud Gateway 2.2.3 官方使用说明(2)-- 路由filter(上)
Spring Cloud Gateway 2.2.3 官方使用说明(2)-- 路由filter(下)
Spring Cloud Gateway 2.2.3 官方使用说明(3)-- Global filter
Spring Cloud Gateway 2.2.3 官方使用说明(4)-- HttpHeader Filters
Spring Cloud Gateway 2.2.3 使用说明(5)-- TLS 和 SSL
Spring Cloud Gateway 2.2.3 使用说明(6)-- 其它配置
Spring Cloud Gateway 2.2.3 使用说明(7)-- actuator

Spring Cloud Gateway 2.2.3 使用说明(8)-- 开发指导

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiegwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值