gpt4 book ai didi

java - 你如何在 Spring Cloud Gateway (Webflux) POST 过滤器中读取响应主体

转载 作者:行者123 更新时间:2023-12-02 12:57:27 24 4
gpt4 key购买 nike

Spring Cloud Gateway 记录了一个后过滤阶段,如下所示:https://cloud.spring.io/spring-cloud-static/Greenwich.RELEASE/single/spring-cloud.html#_writing_custom_gatewayfilter_factories

我已经实现了一个在过滤前阶段没有任何内容的过滤器,但我想在将其提交给等待响应成功的客户端之前在过滤后阶段操作响应主体。

我已经设法成功地改变了响应,但是我没有找到如何从成功的代理请求中实际读取原始响应的解决方案。我想我已经尝试了几乎所有方法,而且我知道在 webflux 流中间读取正文可能不是最佳做法,因为它有点违背了整个目的。但这让我抓狂,仅仅从响应中读取数据是如此困难。

我的过滤器看起来像这样:

class PostFilter : AbstractGatewayFilterFactory<PostFilter.Config>(Config::class.java) {
@Autowired
private lateinit var tokenService: TokenService

/* This is required when implementing AbstractGatewayFilterFactory.
* With config we could pass filter configurations in application.yml route config
* This can be used if it is needed to parametrise filter functionality
*/
class Config

override fun apply(config: Config?): GatewayFilter {
return GatewayFilter { exchange: ServerWebExchange, chain: GatewayFilterChain ->

chain.filter(exchange).then(Mono.defer {
val response = exchange.response
val bytes: ByteArray = "Some text".toByteArray(StandardCharsets.UTF_8)
val buffer: DataBuffer = exchange.response.bufferFactory().wrap(bytes)
response.headers.contentLength = bytes.size.toLong()

// How do I get the original response?
response.writeWith(Flux.just(buffer))
})


}
}
}

我找到了这个例子:https://github.com/spring-cloud/spring-cloud-gateway/blob/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/WebClientWriteResponseFilter.java我在哪里看到 ClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR); 但是当我尝试它时,它不包含可用于获取正文的 ClientResponse 对象。相反,我得到了无法获取响应主体的 netty 的 HttpClientResponse 对象。

我搜索了许多 stackoverflow 主题,涵盖了看起来有点相似但实际上并不相同的问题。

我也尝试过这种方法,如 https://github.com/spring-cloud/spring-cloud-gateway/issues/177#issuecomment-361411981您可以在其中使用 ServerHttpResponseDecorator 来读取正文。但是,如果调用 writeWith() 方法,它只会读取正文。因此,如果我想要原始响应,我必须将原始响应作为 DataBuffer 重新写入,以便触发 writeWith。但如果我有 DataBuffer,我就根本不需要整个 ServerHttpResponseDecorator

所以,请帮帮我——我的头撞到了墙上,我想放弃了。我通常从不放弃,因为我觉得这应该是微不足道的,因为它是如此简单:“在代理请求后读取响应主体”。

有什么想法吗?

最佳答案

以可读格式获取响应的一种方法是(改编自 NettyWriteResponseFilter:https://github.com/spring-cloud/spring-cloud-gateway/blob/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyWriteResponseFilter.java)是使用 Netty Connection:

            val connection: Connection = exchange.getAttribute(CLIENT_RESPONSE_CONN_ATTR) ?: error("Connection not found")
val factory: NettyDataBufferFactory = response.bufferFactory() as NettyDataBufferFactory
val body = connection.inbound().receive().retain().map(factory::wrap).next()
body.doOnSuccess {
val dest = ByteArray(it.readableByteCount())
it.read(dest)
val originalResponse = String(dest, StandardCharsets.UTF_8)
println(originalResponse)
}

关于java - 你如何在 Spring Cloud Gateway (Webflux) POST 过滤器中读取响应主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59286520/

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