gpt4 book ai didi

spring-boot - Spring Cloud 网关在过滤器中发送响应

转载 作者:行者123 更新时间:2023-12-03 23:50:15 30 4
gpt4 key购买 nike

我正在使用 Spring Cloud Gateway 作为边缘服务器。
这是流量

如果请求有一个名为“x-foo”的 header ,则找到 header 值,从另一个服务器获取一个字符串并将该字符串作为响应发送,而不是实际代理请求。

这是过滤器 DSL 的代码

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

Foo 过滤器的代码
@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 代码,注入(inject)的 header 出现在响应中,但响应中的数据不可用。

最佳答案

这就是我开始工作的方式。

  • 使用flatMap而不是 doOnSuccess
  • 不要使用 thenswitchIfEmpty改为使用 onErrorResume
  • 返回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));
    }
    }

    关于spring-boot - Spring Cloud 网关在过滤器中发送响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59694893/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com