Spring cloud 杰克逊流媒体api&;Spring云网关中的WebFlux响应体
我对SpringCloudGateway和SpringWebFlux还很陌生 我有一个需求,我需要收集响应中数据元素的所有ID以用于日志记录 我以一种非常占用内存的方式完成了这项工作,方法是将数据缓冲区读入一个字节数组,对其进行解析,然后将其包装成一个数据缓冲区并将其传递 然而,当响应很大时,这是不可行的,我正在使用Jackson流媒体API,所以这看起来很愚蠢 有人对如何做到这一点有什么建议吗?我所看到的所有例子似乎都是以类似的方式实现的,即在内存中缓冲整个响应 当前版本(Groovy): 类DataIdResponseHandler扩展了ServerHttpResponseDecorator{ 最终数据缓冲工厂数据缓冲工厂 DataIdResponseHandler(服务器HttpResponse委托){ 超级(代表) dataBufferFactory=delegate.bufferFactory() } @凌驾Spring cloud 杰克逊流媒体api&;Spring云网关中的WebFlux响应体,spring-cloud,spring-cloud-gateway,Spring Cloud,Spring Cloud Gateway,我对SpringCloudGateway和SpringWebFlux还很陌生 我有一个需求,我需要收集响应中数据元素的所有ID以用于日志记录 我以一种非常占用内存的方式完成了这项工作,方法是将数据缓冲区读入一个字节数组,对其进行解析,然后将其包装成一个数据缓冲区并将其传递 然而,当响应很大时,这是不可行的,我正在使用Jackson流媒体API,所以这看起来很愚蠢 有人对如何做到这一点有什么建议吗?我所看到的所有例子似乎都是以类似的方式实现的,即在内存中缓冲整个响应 当前版本(Groovy): 类
Mono writeWith(publisher请发布服务器HttpResponseDecorator的代码好吗?@JonckvanderKogel添加了有问题的当前版本。问题似乎出在实际响应被读入内存的dataBuffer.read方法中。也许一个好的方法是不使用read(字节[])使用dataBuffer.asInputStream()的方法函数,您可以在其中以流式方式解析JSON,如下所述:。如果我有时间,我将尝试创建一个工作PoC。如果您设法使其工作,请在此处发布您的解决方案,因为这是一个非常有趣的主题!使用输入流的问题是,您必须从输入流读取数据,并捕获输出我的解析器可以同时获取inputstream和字节数组,但由于我在writeWith中以非反应性的方式完成了大部分工作,我认为这是一条死胡同。我曾想过做一些类似于共享流量的事情,一个订阅者解析主体,另一个订阅者编写响应,因此就像以非反应性的方式一样,有一个outputstream包装器,它将位于读取操作中,并在写入响应时缓慢地将字节送入解析器。之后它将得到解析操作的结果。
class DataIdResponseHandler extends ServerHttpResponseDecorator {
final DataBufferFactory dataBufferFactory
DataIdResponseHandler(ServerHttpResponse delegate) {
super(delegate)
dataBufferFactory = delegate.bufferFactory()
}
@Override
Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body
return super.writeWith(fluxBody.map { dataBuffer ->
byte[] content = new byte[dataBuffer.readableByteCount()]
dataBuffer.read(content)
List<String> dataIds = DataIdParser.parseFromByteArray(content)
DataIdCollector.add(dataIds)
return dataBufferFactory.wrap(content)
})
}
}
return super.writeWith(fluxBody.doOnNext { DataBuffer dataBuffer ->
List<String> dataIds = DataIdParser.parseFromByteArray(dataBuffer.toString(Charset.defaultCharset()).bytes)
Logger logger = LoggerFactory.getLogger(DataIdResponseFilter)
logger.info(dataIds.toString())
})