当前位置: 首页 > 知识库问答 >
问题:

Spring云网关在过滤器中发送响应

谯和煦
2023-03-14

我正在使用spring云网关作为边缘服务器。这就是流程

@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("foo-filter", r -> r.header('x-foo').and().header("x-intercepted").negate()
                        .filters(f -> f.filter(fooFilter))
                        .uri("http://localhost:8081")) // 8081 is self port, there are other proxy related configurations too
                .build();
    }
@Component
@Slf4j
public class FooFilter implements GatewayFilter {

    @Autowired
    private ReactiveRedisOperations<String, String> redisOps;

    @Value("${header-name}")
    private String headerName;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        var foo = request.getHeaders().getFirst(headerName);

        return redisOps.opsForHash()
                .get("foo:" + foo, "response")
                .doOnSuccess(s -> {
                    log.info("data on success");
                    log.info(s.toString()); // I am getting proper response here
                    if (s != null) {
                        ServerHttpResponse response = exchange.getResponse();
                        response.setStatusCode(HttpStatus.OK);
                        response.getHeaders().set("x-intercepted", "true");

                        byte[] bytes = s.toString().getBytes(StandardCharsets.UTF_8);

                        DataBuffer buffer = response.bufferFactory().wrap(bytes);

                        response.writeWith(Mono.just(buffer));

                        response.setComplete();
                    }
                })
                .then(chain.filter(exchange));
    }

}

问题是,响应有响应是得到正确的200代码,注入的头是在响应上出现,但数据是不可用的响应。

共有1个答案

周凯捷
2023-03-14

我就是这样开始工作的。

  • 使用flatmap而不是doonsuccess
  • 不要使用thenswitchifempt,而是使用onerrorremume
  • 返回response.writeWith
    @Component
    @Slf4j
    public class FooFilter implements GatewayFilter {
    
        @Autowired
        private ReactiveRedisOperations<String, String> redisOps;
    
        @Value("${header-name}")
        private String headerName;
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest request = exchange.getRequest();
            var foo = request.getHeaders().getFirst(headerName);
    
            return redisOps.opsForHash()
                    .get("foo:" + foo, "response")
                    .flatMap(s -> {
                        log.info("data on success");
                        log.info(s.toString()); // I am getting proper response here
                        if (s != null) {
                            ServerHttpResponse response = exchange.getResponse();
                            response.setStatusCode(HttpStatus.OK);
                            response.getHeaders().set("x-intercepted", "true");
    
                            byte[] bytes = s.toString().getBytes(StandardCharsets.UTF_8);
    
                            DataBuffer buffer = response.bufferFactory().wrap(bytes);
    
                            return response.writeWith(Mono.just(buffer));
   
                        }else{ return chain.filter(exchange).then(Mono.fromRunnable(() -> {log.info("It was empty")} }
                    })
                    .onErrorResume(chain.filter(exchange));
        }
    }
 类似资料:
  • 我正在尝试将JHipster从使用Zuul迁移到Spring云网关。JHipster使用Eureka来查找路由,我相信我已经正确配置了Spring Cloud Gateway来查找路由并向它们传播访问令牌。下面是我的配置: 我创建了一个pull请求,以显示集成Spring Cloud Gateway后发生了什么变化。 https://github.com/mraible/jhipster-reac

  • 我使用spring cloud gateway将请求路由到我的下游应用程序,我定义了如下的路由器 路由工作正常,现在我需要添加一个预过滤器,它可以执行一些预条件并获得路由路径。但不知道如何动态更改uri。uri(“http://localhost:8081/test") 下面是我在preFilter中尝试的代码。 因此,我需要根据我的自定义过滤器中的db查找返回,从传入路径/user/test/*

  • 我遵循下面的示例来实现spring集成网关。 问题:无法从服务激活器发送的网关上获得响应。 网关应答通道是"最佳应答通道"。 服务激活器写入同一个通道。 所有的自定义方法都被执行,响应被组成,但是从来没有被发送出去。知道这里缺少什么吗?我的配置在流程中也有一个分散收集。

  • 我是Spring启动滤镜的新手 我需要将servlet(impl)产生的响应修改成某种模式。 例如,GetProductImpl将给出 所以在它返回给客户端之前,我需要将其修改为(有点像将响应放在模块下)(对于所有servlet的所有响应) 我寻找任何可以让我做到这一点的方法,因为在impl内部做这件事是没有意义的,因为如果像这样,我需要为所有的impl做(这是很多的,不可行的)。 如果任何人有任

  • 当我试图从zuul预过滤器访问另一个REST API(在ZUUL路由中注册)时,我面临的问题是,调用变得递归,即它一次又一次地运行我的预过滤器代码。我的Usecase如下- > 在Zuul方法中,我正在验证头中传递的令牌。 在验证令牌之后,我调用一个rest服务(用户位置服务)来获取用户详细信息。我的用户位置服务本身已在ZUUL注册,如下所示: 问题是JWT令牌验证代码正在一次又一次地运行,您能否