基于请求主体内容的Spring Cloud Gateway路由

时间:2019-08-03 02:20:49

标签: reactive-programming spring-cloud-gateway

我需要创建一个接收传入请求的反向代理,并根据请求正文的内容将请求路由到特定的URI。

这是针对路由微服务的,它充当反向代理,并根据来自每个请求正文的某些信息进行路由。这意味着对于每个请求,我都需要解析请求主体并获取“用户名”字段,然后进行JDBC连接以从数据库中获取其他信息。根据数据库中的信息,最终它将把请求重定向到正确的URI。

从现在的情况来看,我有2种阻止方法。第一个是请求正文的解析,另一个是到数据库的JDBC连接。我知道我不应该在网关过滤器中放置任何阻塞调用。我只是不知道在这种情况下该怎么办。我可以让两个操作都异步运行,但最后我仍然需要数据库中的信息来进行路由。

    @Bean
    public RouteLocator apiLocator(RouteLocatorBuilder builder, XmlMapper xmlMapper) {
        return builder.routes()
            .route(r -> r
                .path("/test")
                .and()
                .readBody(String.class, s -> true)  // Read the request body, data will be cached as cachedRequestBodyObject
                .filters(f -> f.filter(new GatewayFilter() {
                    @Override
                    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                        try {
                            // The following method is blocking and should not be put here
                            xmlMapper.readValue((String) exchange.getAttribute("cachedRequestBodyObject"), Map.class);
                        } catch (Exception e) {
                            //TODO
                        }
                        return chain.filter(exchange);
                    }
                }))
                .uri("http://localhost:8080"))
            .build();
    }

上面的示例仅包括阻塞解析,因为我的请求主体基于XML。我的IDE警告我在那里有阻塞呼叫,对此我深表感谢。

任何帮助将不胜感激。谢谢大家!

1 个答案:

答案 0 :(得分:0)

经过一些研究,Mono.fromCallable似乎很合适。然后我直接在github存储库下问了同样的问题,事实证明,使用servlet应用可能会更好。如果您有兴趣了解我的想法,请在这里https://github.com/spring-cloud/spring-cloud-gateway/issues/1229