【问题标题】:Spring cloud gateway: How to create a filterSpring Cloud Gateway:如何创建过滤器
【发布时间】:2018-07-09 06:23:33
【问题描述】:

我是 Spring Cloud Gateway 的新手。

我一直在观看 SpringDeveloper 频道的一些 youtube 视频,并且正在研究以下示例:

@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {

    return builder.routes()
            .route(r -> r.path("/get")
            .addRequestHeader("X-SpringOne", "Awesome")
            .uri("http://httpbin.org:80"))
            .build();
}

在查看 Spring Cloud Gateway 之前,我还查看了 Spring Netflix Zuul。我知道在 Netflix Zuul 中,您可以通过创建一个扩展 ZuulFilter 的类并将其定义为 prepostroute 等来创建过滤器。

但是我想知道如何使用 Spring 云网关创建 PRE/POST 过滤器?

非常感谢任何帮助/建议。

谢谢。

【问题讨论】:

标签: spring-boot spring-cloud spring-cloud-netflix


【解决方案1】:

这里的前置过滤器是AddRequestHeader(代码在chain.filter()调用之前执行):

public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header(config.getName(), config.getValue())
                    .build();

            return chain.filter(exchange.mutate().request(request).build());
        };
    }

}

对于“后”过滤器,这里是 SetStatus(代码在 chain.filter(exchange).then() 中的 lambda 中运行):

public class SetStatusGatewayFilterFactory extends AbstractGatewayFilterFactory<SetStatusGatewayFilterFactory.Config> {
    @Override
    public GatewayFilter apply(Config config) {
        final HttpStatus status = ServerWebExchangeUtils.parse(config.status);
        return (exchange, chain) -> {

            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // check not really needed, since it is guarded in setStatusCode,
                // but it's a good example
                if (!exchange.getResponse().isCommitted()) {
                    setResponseStatus(exchange, status);
                }
            }));
        };
    }
}

【讨论】:

  • @spencergibb 过滤器是如何添加到配置或路由定位器中的?如果我通过 Bean 注释将它添加到应用程序配置中,它永远不会被触发。
  • 有人解决了这个问题吗?我找不到如何使用 RouteLocatorBuilder 将自定义过滤器“注册”到路由。
【解决方案2】:

这是 Kotlin 中的一个简单示例:URI http://.../customers 映射到从名为customer 并附加“/”。此外,转发的请求通过附加的标头条目得到增强。希望这会有所帮助。

@SpringBootApplication
class Application {
    @Bean
    fun routes(builder: RouteLocatorBuilder) = builder.routes {
        route {
            path("/customers")
            filters {
                setPath("/")
                addRequestHeader("aKey", "aValue")
            }
            uri("lb://customer")
        }
    }
}

【讨论】:

  • 我认为他正在寻找如何创建自定义过滤器
【解决方案3】:

我不确定这是不是正确的做法,因为我也在尝试实现这种行为,我在想这是否是需要做的事情:

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

public class CustomFilter implements GatewayFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //code for PRE filter

        Mono<Void> v = chain.filter(exchange);

        //code for POST filter
        return v;
    }
}

让我知道这是否适合您,或者您是否找到了其他解决方案。

【讨论】:

    猜你喜欢
    • 2020-05-31
    • 2019-10-07
    • 2020-11-14
    • 2020-08-26
    • 2020-11-04
    • 2018-06-21
    • 2015-04-12
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多