Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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
Java 如何阅读SpringCloudGateway(Webflux)后期过滤器中的响应正文_Java_Spring_Kotlin_Spring Webflux_Spring Cloud Gateway - Fatal编程技术网

Java 如何阅读SpringCloudGateway(Webflux)后期过滤器中的响应正文

Java 如何阅读SpringCloudGateway(Webflux)后期过滤器中的响应正文,java,spring,kotlin,spring-webflux,spring-cloud-gateway,Java,Spring,Kotlin,Spring Webflux,Spring Cloud Gateway,Spring Cloud Gateway记录了一个后过滤阶段,如下所示: 我已经实现了一个过滤器,它在预过滤器阶段没有任何内容,但是我想在将响应主体提交给等待响应成功的客户端之前,在后过滤器阶段操纵响应主体 我已经成功地修改了响应,但是对于如何从成功的代理请求中读取原始响应,我还没有找到解决方案。我想我已经尝试过几乎所有的事情,我知道这也许不是最好的做法来阅读身体在网络流量的中间,因为它击败了整个目的。但这让我抓狂,仅仅从响应中读取数据是如此困难 我的过滤器如下所示: class PostFil

Spring Cloud Gateway记录了一个后过滤阶段,如下所示:

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

我已经成功地修改了响应,但是对于如何从成功的代理请求中读取原始响应,我还没有找到解决方案。我想我已经尝试过几乎所有的事情,我知道这也许不是最好的做法来阅读身体在网络流量的中间,因为它击败了整个目的。但这让我抓狂,仅仅从响应中读取数据是如此困难

我的过滤器如下所示:

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))
            })


        }
    }
}
class PostFilter:AbstractGatewayFilterFactory(Config::class.java){
@自动连线
私有lateinit var令牌服务:令牌服务
/*这是实现AbstractGatewayFilterFactory时所必需的。
*使用config,我们可以在application.yml route config中传递过滤器配置
*如果需要参数化过滤器功能,可以使用此选项
*/
类配置
覆盖应用(配置:配置?):网关过滤器{
返回GatewayFilter{exchange:ServerWebExchange,链:GatewayFilterChain->
chain.filter(交换)。然后(Mono.defer{
val response=exchange.response
val bytes:ByteArray=“Some text”.toByteArray(StandardCharsets.UTF_8)
val buffer:DataBuffer=exchange.response.bufferFactory().wrap(字节)
response.headers.contentLength=bytes.size.toLong()
//我如何得到最初的答复?
response.writeWith(Flux.just(buffer))
})
}
}
}
我发现了这个例子:我看到
ClientResponse ClientResponse=exchange.getAttribute(CLIENT\u RESPONSE\u ATTR)
但是当我尝试它时,它不包含可用于获取主体的
ClientResponse
对象。相反,我得到了netty的
HttpClientResponse
对象,它无法获得响应体

我搜索了许多stackoverflow主题,涵盖了看起来有点相似但实际上没有一个是相同的问题

我还尝试了这种方法,您可以使用
ServerHttpResponseDecorator
读取正文。但是,它仅在调用
writeWith()
方法时读取正文。因此,如果我想要原始响应,我必须以
DataBuffer
的形式获取原始响应,以便再次写入,从而触发writeWith。但是,如果我使用的是as
DataBuffer
,我根本不需要整个
ServerHttpResponseDecorator

所以请帮帮我,我的头撞到了墙上,我想放弃。我通常从不放弃,因为我觉得这样做应该是微不足道的,因为这是一件非常简单的事情:“在代理请求之后阅读响应体”


有什么想法吗?

获取可读格式响应的一种方法是(改编自NettyWriteResponseFilter:)使用Netty连接:

            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)
            }

这看起来还可以,可以使用。但这让我想知道使用Netty连接对象是否是正确的方法?如果这能解决我的问题,我很高兴,但如果有人有更优雅的解决方案,我想知道?@LeoMelin你能在spring cloud gateway中找到一种进入身体的方法吗?我尝试了上面提到的方法,但没有看到反应。