Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin Spring Cloud Gateway自定义筛选器:WebClient.create().post()在测试时导致挂起_Kotlin_Spring Webflux_Spring Cloud Gateway - Fatal编程技术网

Kotlin Spring Cloud Gateway自定义筛选器:WebClient.create().post()在测试时导致挂起

Kotlin Spring Cloud Gateway自定义筛选器:WebClient.create().post()在测试时导致挂起,kotlin,spring-webflux,spring-cloud-gateway,Kotlin,Spring Webflux,Spring Cloud Gateway,所以我创建了一个自定义过滤器,当被访问时,它将创建一个webflux客户端并发布到一个预定的url。这在运行时似乎可以正常工作,但在测试此代码时,测试将挂起(直到我取消测试)。因此,我觉得除了无法完成测试以确保此路径正常工作之外,还可能存在内存泄漏。如果我将WebClient方法切换到get(),则过滤器的测试结果正常。有一个post()我不确定少了什么 @Component class ProxyGatewayFilterFactory: AbstractGatewayFilterFactor

所以我创建了一个自定义过滤器,当被访问时,它将创建一个webflux客户端并发布到一个预定的url。这在运行时似乎可以正常工作,但在测试此代码时,测试将挂起(直到我取消测试)。因此,我觉得除了无法完成测试以确保此路径正常工作之外,还可能存在内存泄漏。如果我将
WebClient
方法切换到
get()
,则过滤器的测试结果正常。有一个
post()
我不确定少了什么

@Component
class ProxyGatewayFilterFactory: AbstractGatewayFilterFactory<ProxyGatewayFilterFactory.Params>(Params::class.java) {
    override fun apply(params: Params): GatewayFilter {
        return OrderedGatewayFilter(
                GatewayFilter { exchange, chain ->
                    exchange.request.mutate().header("test","test1").build()
                    WebClient.create().post()
                            .uri(params.proxyBasePath)
                            .body(BodyInserters.fromDataBuffers(exchange.request.body))
                            .headers { it.addAll(exchange.request.headers) }
                            .exchange()
                            .flatMap {
                                println("the POST statusCode is "+it.statusCode())
                                Mono.just(it.statusCode().is2xxSuccessful)
                            }
                            .map {
                                exchange.request.mutate().header("test", "test2").build()
                                println("exchange request uri is " + exchange.request.uri)
                                println("exchange response statusCode is "+ exchange.response.statusCode)
                                exchange
                            }
                            .flatMap(chain::filter)
                }, params.order)
}
@组件
类ProxyGatewayFilterFactory:AbstractGatewayFilterFactory(Params::class.java){
覆盖应用(参数:参数):网关过滤器{
退货订单GatewayFilter(
网关筛选器{交换,链->
exchange.request.mutate().header(“test”、“test1”).build()
WebClient.create().post()
.uri(参数proxyBasePath)
.body(BodyInserters.fromDataBuffers(exchange.request.body))
.headers{it.addAll(exchange.request.headers)}
.exchange()
.平面图{
println(“POST状态码是”+it.statusCode())
Mono.just(it.statusCode().is2xx成功)
}
.地图{
exchange.request.mutate().header(“test”、“test2”).build()
println(“交换请求uri为”+exchange.request.uri)
println(“exchange响应状态代码为”+exchange.response.statusCode)
交换
}
.flatMap(链::过滤器)
},参数顺序)
}

取自文档,如果使用
交换
您有义务消耗身体

与retrieve()不同,在使用exchange()时,应用程序有责任使用任何响应内容,而不考虑场景(成功、错误、意外数据等)。不这样做可能会导致内存泄漏。Javadoc for ClientResponse列出了使用正文的所有可用选项。通常更喜欢使用retrieve()除非您有充分的理由使用exchange(),它允许在决定如何或是否使用响应之前检查响应状态和头


此api已在最新版本的spring framework 5.3.0中更改,现在spring将强制您使用正文,因为开发人员实际上没有阅读文档。

如何在筛选器中执行此操作?链接中有几个示例说明如何使用正文。例如
.exchange().flatMap(response->response.bodyToMono(Void.class));
这里我使用Void是因为我们不关心身体。我对这种反应性的东西太陌生了……我实际上使用了它。releaseBody()这似乎也起作用。身体本身仍然通过过滤器传递?如果我不归还它或释放它,我不会丢失它。我真的不明白你想通过所有的变异实现什么,为什么你要更改头等等。你问你是否有内存泄漏,我告诉你是的,以及如何修复它。W我不知道你的业务需求是什么。我建议如果你是新手,先阅读
reactor文档
,然后再阅读
webflux文档
反应式编程与普通编程有很大的不同,你不可能通过谷歌一点点就能找到。如果你需要你得到的身体稍后,从webclient调用中,您需要在
flatMap
中提取它,以便webflux可以关闭底层tcp连接。然后将正文传递到需要使用它的任何地方。