gateway增加动态请求头

1.实现自己的Filter


public class MyFilter implements  GatewayFilter, Ordered {

    private static final Log log = LogFactory.getLog(GatewayFilter.class);
    private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest req = exchange.getRequest();
        HttpHeaders httpHeaders = req.getHeaders();
        ServerHttpRequest.Builder requestBuilder = req.mutate();
        Long timestamp = (new Date().getTime() / 1000);
       System.out.println(timestamp);
        requestBuilder.headers(k -> k.remove("x-tif-timestamp"));
        requestBuilder.header("x-tif-timestamp", timestamp.toString());
        ServerHttpRequest request = requestBuilder.build();
        exchange.mutate().request(request).build();
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

2.注册到Filter链里面

  @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("path_route", r -> r.path("/get")
                        .uri("http://httpbin.org"))
                .route("host_route", r -> r.path("/ebus")
                        .filters(f -> f.filter(
                                new SignatrueFilter())
                                .filter(new MyFilter())
                        )
                        .uri(""))
                .build();
    }

3.总结

需要注意的是这里面的几个函数式写法。

filters()接受的参数是一个Function ;

GatewayFilterSpec是重点,GatewayFilterSpec的方法呢都是返回的本身调用。所以可以一直调用下去。这种设计方式叫啥名忘了,有朋友知道回复一下。

GatewayFilterSpec里面有一个很重要的方法需要注意就是filter方法,他是一个构造函数哈,看一下它的实现

 public GatewayFilterSpec filter(GatewayFilter gatewayFilter) {
        if (gatewayFilter instanceof Ordered) {
            this.routeBuilder.filter(gatewayFilter);
            return this;
        } else {
            return this.filter(gatewayFilter, 0);
        }
    }

把一个GatewayFilter类型包装成GatewayFilterSpec。这就是自定义GatewayFilterSpec的整个流程哈。本来是为了增加一个时间戳请求头的。使用addRequestHeader方法添加的时间戳初始化后就不变了。看下它的代码,接受的就是两个String。没办法传递function就去。所以暂时只想到了重写自定义GatewayFilterSpec ,这个方法。

 public GatewayFilterSpec addRequestHeader(String headerName, String headerValue) {
        return this.filter(((AddRequestHeaderGatewayFilterFactory)this.getBean(AddRequestHeaderGatewayFilterFactory.class)).apply((c) -> {
            c.setName(headerName).setValue(headerValue);
        }));
    }

你可能感兴趣的:(java,spring)